118 lines
5.2 KiB
Markdown
118 lines
5.2 KiB
Markdown
# Lecture 2 --- STL Strings & Vectors
|
||
|
||
- STL Strings, char arrays (C-style Strings), & converting between these two types
|
||
- L-values vs. R-values
|
||
- STL Vectors as “smart arrays”
|
||
|
||
## 2.1 Character Arrays and String Literals
|
||
|
||
- In the line below "Hello!" is a string literal and it is also an array of characters (with no associated variable
|
||
name).
|
||
```cpp
|
||
cout << "Hello!" << endl;
|
||
```
|
||
- A char array can be initialized as:
|
||
```c
|
||
char h[] = {'H', 'e', 'l', 'l', 'o', '!', '\0'};
|
||
```
|
||
or as:
|
||
```c
|
||
char h[] = "Hello!";
|
||
```
|
||
In either case, array h has 7 characters, the last one being the null character.
|
||
- The C language provides many functions for manipulating these “C-style strings”. We don’t study them much
|
||
anymore because the “C++ style” STL string library is much more logical and easier to use. If you want
|
||
to find out more about functions for C-style strings look at the cstdlib library http://www.cplusplus.com/
|
||
reference/cstdlib/.
|
||
- One place we do use them is in file names and command-line arguments, which you will use in Homework 1.
|
||
|
||
## 2.2 Conversion Between Standard Strings and C-Style String Literals
|
||
|
||
- We regularly convert/cast between C-style & C++-style (STL) strings. For example:
|
||
|
||
```cpp
|
||
std::string s1( "Hello!" );
|
||
std::string s2( h );
|
||
```
|
||
|
||
where h is as defined above.
|
||
- You can obtain the C-style string from a standard string using the member function c_str, as in s1.c_str().
|
||
|
||
## 2.3 STL Vectors: a.k.a. “C++-Style”, “Smart” Arrays
|
||
|
||
- Standard library “container class” to hold sequences.
|
||
- A vector acts like a dynamically-sized, one-dimensional array.
|
||
Capabilities:
|
||
– Holds objects of any type.
|
||
– Starts empty unless otherwise specified.
|
||
– Any number of objects may be added to the end — there is no limit on size.
|
||
– It can be treated like an ordinary array using the subscripting operator.
|
||
– A vector knows how many elements it stores! (unlike C arrays)
|
||
– There is NO automatic checking of subscript bounds.
|
||
|
||
Here’s how we create an empty vector of integers:
|
||
```cpp
|
||
std::vector<int> scores;
|
||
```
|
||
- Vectors are an example of a templated container class. The angle brackets < > are used to specify the type of object (the “template type”) that will be stored in the vector.
|
||
- push back is a vector function to append a value to the end of the vector, increasing its size by one. <!--This is an O(1) operation (on average).-->
|
||
– There is NO corresponding push front operation for vectors.
|
||
- size is a function defined by the vector type (the vector class) that returns the number of items stored in the vector.
|
||
- After vectors are initialized and filled in, they may be treated just like arrays.
|
||
– In the line
|
||
```cpp
|
||
sum += scores[i];
|
||
```
|
||
scores[i] is an “r-value”, accessing the value stored at location i of the vector.
|
||
– We could also write statements like
|
||
```cpp
|
||
scores[4] = 100;
|
||
```
|
||
to change a score. Here scores[4] is an “l-value”, providing the means of storing 100 at location 4 of the vector.
|
||
– It is the job of the programmer to ensure that any subscript value i that is used is legal —- at least 0 and strictly less than scores.size().
|
||
|
||
## 2.4 Initializing a Vector — The Use of Constructors
|
||
Here are several different ways to initialize a vector:
|
||
- This “constructs” an empty vector of integers. Values must be placed in the vector using push_back.
|
||
```cpp
|
||
std::vector<int> a;
|
||
```
|
||
- This constructs a vector of 100 doubles, each entry storing the value 3.14. New entries can be created using
|
||
push_back, but these will create entries 100, 101, 102, etc.
|
||
```cpp
|
||
int n = 100;
|
||
std::vector<double> b( 100, 3.14 );
|
||
```
|
||
- This constructs a vector of 10,000 ints, but provides no initial values for these integers. Again, new entries can
|
||
be created for the vector using push_back. These will create entries 10000, 10001, etc.
|
||
```cpp
|
||
std::vector<int> c( n*n );
|
||
```
|
||
- This constructs a vector that is an exact copy of vector b.
|
||
```cpp
|
||
std::vector<double> d( b );
|
||
```
|
||
- This is a compiler error because no constructor exists to create an int vector from a double vector. These are
|
||
different types.
|
||
```cpp
|
||
std::vector<int> e( b );
|
||
```
|
||
|
||
## 2.5 Passing Vectors (and Strings) As Parameters
|
||
|
||
The following outlines rules for passing vectors as parameters. The same rules apply to passing strings.
|
||
- If you are passing a vector as a parameter to a function and you want to make a (permanent) change to the
|
||
vector, then you should pass it by reference.
|
||
– This is illustrated by the function read scores in the program median grade.
|
||
– This is very different from the behavior of arrays as parameters.
|
||
- What if you don’t want to make changes to the vector or don’t want these changes to be permanent?
|
||
– The answer we’ve learned so far is to pass by value.
|
||
– The problem is that the entire vector is copied when this happens! Depending on the size of the vector,
|
||
this can be a considerable waste of memory.
|
||
- The solution is to pass by constant reference: pass it by reference, but make it a constant so that it can not
|
||
be changed.
|
||
– This is illustrated by the functions compute avg and std dev and compute median in the program
|
||
median grade.
|
||
- As a general rule, you should not pass a container object, such as a vector or a string, by value because of the
|
||
cost of copying.
|