Strings, Vectors, And Arrays
The standard library defines a number of additiaonal types of a higher-level nature that computer hardware usually does not implement directly.
3.1 Namespace using Declarations
Headers Should Not Include using
Declarations: The contents of a header are copied into the including program’s text. If a header has a using
declaration, then it will pollute all scope with such using
statement.
3.2 Library string
3.2.1 Defining and Initializeing strings
1 | string s4(10, 'c'); // s4 is cccccccccc |
Direct and Copy Forms of Initialization:
1 | string s5 = "hiya"; // copy initialization |
3.2.2 Operations on string
s
Table: String Operations: On page. 86.
1 | getline(is, s); // Reads a line of input from is into s, returns is. |
Using getline
to Read an Entire Line: if you want to take the input and keep the whitespace in input:
1 | int main() |
The string::size_type Type: string::size_type
returns a size_type value. If n ins an int that holds a negative value, then s.size() < n will almost surely evaluate as true. It yields true because the negative value in n will convert to a large unsigned value.
Adding Literals and strings: When we mix strings and string or character literals, at least one operand to each + operator must be of string type.
1 | string s5 = "hello" + ", "; // error: no string operand |
3.2.3 Dealing with the Characters in a string
Advice: Use the C++ version of C Library Headers. Headers in C have names of the form name.h. The C++ version of these headers are named cname–they remove the .h suffix and precede the name with the letterc. The c indicates that the header is part of the C library.cctype
has the same contents as ctype.h
, but in a form that is approprate for C++ programs. In particular, the names defined in the cname
headers are defined inside the std
namespace, whereas those defined in the .h versions are not.
Note:
string.h
contains old functions likestrcpy
,strlen
for C style null-terminated strings, usecstring
instead.string
primarily contains thestd::string
,std::wstring
and other classes.
Use Range-Based for to process every Character: Introduced in C++ 11, while the expression
should represent a sequence.
1 | for (declaration : expression) |
Example code:
1 | string s("Hello world!!!"); |
Process Only Some Characters: We can use a subscript or an iterator. Note that the subscript will be converted to unsigned int.
Using a Subscript for Random Access:
1 | const string hexdigits = "0123456789ABCDEF"; |
3.3 Library vector Type
A vector is a class template. C++ has both class and function templates.The process that the compiler uses to create classees or functions from templates is called Instantiation.
Note: vector is a template, not a type. Types generated from vector must include the element type, for example, vector<int>
. Some compilers may require the old-style declarations for a vector of vectors, for example, vector<vector<int> >
.
3.3.1 Deifining and Initializing vectors
1 | vector<T> v1; // vector that holds objects of type T. Default initialization; v1 is empty |
Key Concept: vectors grow efficiently: If differing element values are needed, it is usually more efficient to define an empty vector and add elements as the values we need become known at run time. Moreover, vector offers capabilityes to allow us to further enhance run-time performance when we add elements. Deifne a vector of a specific size could result in poorer performance.
Warning: The body of a range for
must not change the size of the sequence over which it is iterating.
3.3.2 Other vector Operations
Warning: buffer overflow errors are the result of subscripting elements that don`t exst. Such bugs are the most common cause of security problems in PC and other applications.
3.4 Introducing Iterators
All of the library containers have iterators, but only a few of them support the subscript operator. string
is not a container, but it supports most of the container operations, string
also supports iterators.
3.4.1 Using Iterators
The iterator returned by end is often referred to as the off-the-end iterator or abbreviated as “the end
iterator”.
Iterator Operations: Iterator only supports a few operations.
1 | *iter; // Returns a reference to the element denoted by the iterator iter. |
MMoving Iterators from One Element to Another: Because the iterator returned from end does not denote an element, it may not be incremented or dereferenced.
Key Concept: Generic Programming: Only a few containers have the subscript operator. Most of thoes iterators do not have the < operator. So C++ programmers use !=
operator in the loop instead of <
operator.
The begin
and end
Operations: The default behavior is often not we want, return iterator
for vector and const_iterator
for const vector, while we usually want const
type to read but not to write. It is suggested to use following new functions in new standard.
1 | vector<int> v; |
3.4.2 Iterator Arithmetic
1 | iter + n; // |
Arithmetic Operations on Iterators: Compute an iterator te the element nearest the middle of a vector
:
1 | auto mid = vi.begin() + vi.size() / 2; |
Using Iterator Arithmetic: A classic algorithm that uses iterator arithmetic is binary search.
3.5 Arrays
An array is a data structure that is similar to the library vector
type but offers a different trade-off between performance and flexibility.
An array is a compound type, which is defined based on other type, like reference and pointer.
1 | unsigned cnt = 42; |
By default, the elements in an array are default initialized. Arrays hold objects, thus , there are no arrays of references.
Explicitly Initializing Array Elements:
1 | const unsigned sz = 3; |
Character Arrays Are Special: String literals end with a null character. That null character is copied into the array along with the characters in the literal.
1 | char a1[] = {'C', '+', '+'}; |
No Copi or Assignment: We cannot initialize an array as a copi of another array, nor is it legal to assign one array to another.
Complicated Array Declarations: Read the declaration from inside out and then right to left.
1 | int *ptrs[10]; // ptrs is an array of ten pointers to int |
3.5.2 Accessing the Elements of an Array
Nothing much, you should be able to accesss elements in arrays like in vectors.
3.5.3 Pointers and Arrays
In C++, when we use an array, the compiler ordinarily converts the array to a pointer. The arrays have a special property–in most places when we use an array, the compiler automatically substitutes a poiter to the first elemet:
1 | string nums[] = {"one", "two", "three"}; |
Pointers Are Iterators: In particular, pointers to array elements support the same operations as iterators on vector
or string
.
The Libarary begin
and end
Functions: begin
returns a pointer to the first, and end
returns a pointer one past the last element in the given array. These funcgtions are defined in the iterator
header.
1 | int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
Pointer Arithmetic: Pointers acn use all the iterator operations.
1 | constexpr size_t sz = 5; |
The result of substracting two pointers is a library type named ptrdiff_t
. Like size_t
, the ptrdiff_t
type is a machine-specific type and is defined in the cstddef
header.
Interaction between Dereference and Pointer Arithmetic:
1 | int ia[] = {0, 2, 4, 6, 8}; |
Subscripts and Pointers: In most places when we use the name of an array, we are really using a pointer to the first element in that array. We can use the subscript operator on any pointer, as long as that pointer points to an element (or one past the last element) in an array.
1 | int *p = &ia[2]; // p points to the element indexed by 2 |
Warning: Unlike subscripts for vector
and string
, the index of the built-in subscript operator is not an unsigned
type.
3.5.4 C-Style Character Strings
C Library String Functions: Included in cstring
header file.
1 | strlen(p); // Renturns the length of p, not cunting the null |
Notes: Remember that when we are comparing arraies, we are really using a pointer to the first element in the array.
Caller Is Responsible for Size of a Destination String: For most applications, in addition to being safer, it is also more efficient to use library strings rather than C-style strings.
3.5.5 INterfacing to Older Code
The string
member funciton named c_str
that we can often use to accomplish what we want.
Using an Array to Initialize a vector
: We cannot initialize a built-in array from another array. But we can, and we only can initialize a vector
using an array.
1 | int int_arr[] = {0, 1, 2, 3, 4, 5}; |
3.6 Multidimensional Arrays
Using a Ranf for with Multidimensional Arrays: The range for loop could be done under the new standard.
1 | size_t cnt = 0; |
Notes: To use a multidimensional array in a range for, the loop control variable for all but the innermost array must be references.
1 | int *ip[4]; // array of pointers to int |
Defined Terms
- begin/end: included in
<iterator>
, return the pointers to an array`s begin and end; - buffer overflow: When we use an index that is out-of-range for a container;
- difference_type: A
signed
integral type defined byvector
andstring
that can hold the distance between any two iterators; - ptrdiff_t/size_t: Machine-dependent signed integral type defined in the
cstddef
header that is large enough to held the difference between 2 pointers into the largest possible array;