NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
# Chapter 3. String, Vectors, and Arrays ## 3.1 Namespace using Declarations These names use the scope operator \(::\), which says that compiler should look in the scope of the left-hand operand for the name of the right-hand operand. Code inside headers ordinarily should not use using declarations. If a header has a using declaration, then every program that includes that header gets that same using declaration. ## 3.2 Library string Type A **string** is a variable-length sequence of characters. To use the string type, it must include the string header. ### 3.2.1 Defining and Initialising strings ```cpp string s1; // Default initialisation; s1 is the empty string string s2(s1); // s2 is a copy of s1 string s2 = s1; // Equivalent to s2(s1), s2 is a copy of s1 string s3("value"); // s3 is a copy of the string literal, not including the null string s3 = "value"; // Equivalent to s3("value"), s3 is a copy of the string literal string s4(n, 'c'); // Initialise s4 with n copies of the character 'c' ``` ### 3.2.2 Operations on strings | string Operations | description | | :--- | :--- | | os &lt;&lt; s | Write s onto output stream os. Returns os. | | is &gt;&gt; s | Reads whitespace-separated string from is into s. Returns is. | | getline\(is, s\) | Reads a line of input from is into s. Returns is. | | s.empty\(\) | Returns true if s is empty; otherwise returns false. | | s.size\(\) | Returns the number of characters in s. | | s\[n\] | Returns a reference to the char at position n in s; position start at 0. | | s1 + s2 | Returns a string that is the concatenation of s1 and s2. | | s1 = s2 | Replaces characters in s1 with a copy of s2. | | s1 == s2 | The strings s1 and s2 are equal if they contain the same characters. | | s1 != s2 | Equality is case-sensitive. | | &lt;, &lt;=, &gt;, &gt;= | Comparisons are case-sensitive and use dictionary ordering. | #### Reading an unknown number of strings ```cpp while(cin >> word) { ... } // read until end-of-file while (getline(cin, word)) { ... } // read input a line a time until end-of-file ``` #### Comparing strings 1. If two strings have different lengths and if every character in the shorter string is equal to the corresponding character of the longer string, then the shorter string is less than the longer one. 2. If any characters at corresponding position in the two strings differ, then the result of the string comparison is the result of comparing the first character at which the strings differ. #### Adding strings and Literals ```cpp string s1 = "hello, ", s2 = "world\n"; string s3 = s1 + s2; // s3 is hello, world\n s1 += s2; // equivalent to s1 = s1 + s2 string s4 = "hello", s5 = "world"; string s6 = s4 + ", " + s5 + "\n"; ``` ### 3.2.3 Dealing with the Characters in a string The **range-base for** statement iterates through the elements in a given sequence and performs some operation on each value in that sequence. ```text for (declaration : expression) statement ``` | cctype Function | Description | | :--- | :--- | | isalnum\(c\) | true if c is a letter or a digit. | | isalpha\(c\) | true if c is a letter. | | iscntrl\(c\) | true if c is a control character. | | isdigit\(c\) | true if c is a digit. | | isgraph\(c\) | true if c is not a space but is printable. | | islower\(c\) | true if c is a lowercase letter. | | isprint\(c\) | true if c is a printable character. | | ispunct\(c\) | true if c is a punctuation character. | | isspace\(c\) | true if c is whitespace. | | isupper\(c\) | true if c is uppercase letter. | | isxdigit\(c\) | true if c is a hexadecimal digit. | | tolower\(c\) | if c is an uppercase letter, returns its lowercase equivalent; otherwise return c unchanged. | | toupper\(c\) | if c is a lowercase letter, returns its uppercase equivalent; otherwise returns c unchanged. | ## 3.3 Library vector Type A **vector** is a collection of objects, all of which have the same type. ```cpp #include <vector> using std::vecotr; vector<int> ivec; vector<vector<string>> file; ``` > vector is a template, not a type. Types generated from vector must include the element type. ### 3.3.1 Defining and Initialising vectors ```cpp vector<T> v1; // Defualt initialisation; v1 is empty. vector<T> v2(v1); // v2 has a copy of each element in v1. vector<T> v2 = v1; // Equivalent to v2(v1), v2 is a copy of the elements in v1. vector<T> v3(n, val); // v3 has n elements with value val. vector<T> v4(n); // v4 has n copies of a value-initialised object. vector<T> v5{a, b, c...}; // v5 has as many elements as there are initialisers; elements are initialised by corresponding initialisers. vector<T> v5 = {a, b, c...}; // Equivalent to v5{a, b, c...}. ``` ### 3.3.2 vector Operations | vector Operations | Description | | :--- | :--- | | v.empty\(\) | Returns true if v is empty; otherwise return false. | | v.size\(\) | Returns the number of elements in v. | | v.push\_back\(t\) | Adds an element with value t to end of v. | | v\[n\] | Returns a reference to the element at position n in v. | | v1 = v2 | Replaces the element in v1 with a copy of the elements in v2. | | v1 = {a, b, c...} | Replaces the elements in v1 with a copy of the elements in the comma-separated list. | | ==, != | v1 and v2 are equal if they have the same number of elements and each element in v1 is equal to the corresponding element in v2. | | &lt;, &lt;=, &gt;, &gt;= | Have their normal meanings using dictionary ordering. | ## 3.4 Introducing Iterators The **iterator** provides a method to indirect access to an object. ### 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 | Description | | :--- | :--- | | \*iter | Returns a reference to the element denoted by the iterator iter. | | iter-&gt;mem | Dereferences iter and fetches the member named mem from the underlying element. Equivalent to \(\*iter\).mem. | | ++iter | Increments iter to refer to the next element in the container. | | --iter | Decrements iter to refer the previous element in the container. | | ==, != | Compare two iterator for equality. Two iterators are equal if they denote the same element or if they are the off-the-end iterator for the same container. | | iter + n | Adding an integral value n to an iterator yields an iterator that many elements forward within the container. | | iter - n | Subtracting an integral value n from an iterator yields an iterator that many elements forward within the container. | | iter += n | Compound-assignment for iterator addition. | | iter -= n | Compound-assignment for iterator subtraction. | | iter1 - iter2 | Subtracting two iterators yields the number that when added to the right-hand iterator yields the left-hand iterator. The iterators must denote elements in the same container. | | &gt;, &gt;=, &lt;, &lt;= | One iterator is less than another if it refers to an element that appears in the container before the one referred to by the other iterator. | ## 3.5 Arrays ### 3.5.1 Defining and Initialising Built-in Arrays **Arrays** are a compound type. An array declarator has the form a\[d\], where a is the name being defined and d is the dimension of the array. The dimension specifies the number of elements and must be greater than zero. The dimension must be known at compile time, which means that the dimension must be a constant expression. If we omit the dimension, the compiler infers it from the number of initialiser. If we specify a dimension, the number of initialisers must not exceed the specified size. ```cpp int a2[] = {0, 1, 2}; int a3[5] = {0, 1, 2}; // equivalent to a3[] = {0, 1, 2, 0, 0} ``` Character arrays have an additional form of initialisation, arrays from a string literal. ```cpp char a1[] = {'C', '+', '+'}; // list initialisation, no null char a2[] = {'C', '+', '+', '\0'}; // list initialisation, explicit null char a3[] = "C++"; // null terminator added automatically const char a4[6] = "Daniel"; // error: no space for the null ``` The arrays cannot be initialised and assigned via copying another array. #### Understanding Complicated Array Declarations ```cpp int *ptrs[10]; // ptrs is an array of ten pointers to int int &refs[10]; // error: no arrays of references int (*Parray)[10] = &arr; // Parray points to an array of ten ints int (&arrRef)[10] = arr; // arrRef refers to an array of ten ints int *(&arry)[10] = ptrs; // arry is a reference to an array of ten pointers ``` ### 3.5.2 Accessing the Elements of an Array ```cpp for (auto i : arrays) statement ``` ### 3.5.3 Pointers and Arrays ```cpp string nums[] = {"one", "two", "three"}; // array of strings string *p = &nums[0]; // p points to the first element in nums string *p2 = nums; // equivalent to p2 = &nums[0] int ia[] = {0, 1, 2}; // ia is an array of three ints auto ia2(ia); // ia2 is an int* that points to the first element in ia decltype(ia) ia3 = {0, 1, 2}; // ia3 is an array of three ints ``` To make it easier and safer to pointers, the new library includes two functions, named begin and end. ```cpp int ia[] = {0, 1, 2, 3}; int *beg = begin(ia); int *last = end(ia); ``` #### Pointer Arithmetic It can use the relational operators to compare pointers that point to elements of an array, or one past element in that array. ```cpp int *b = arr, *e = arr + sz; while (b < e) { // use b } int i = 0, sz = 42; int *p = &i, *e = &sz; while (p < e) { ... } // undefined: p and e are unrelated ``` #### Subscripts and Pointers ```cpp int *p = ia; // pointers to the first element in ia int i = *(p + 2); // equialent to i = ia[2] int *p = &ia[2]; // p points to the element indexed by 2 int j = p[1]; // p[1] is the same element as ia[3] int k = p[-2]; // p[-2] is the same element as ia[0] ``` ### 3.5.4 C-Style Character Strings Character string literals are an instance of a more general construct that C++ inherits from C: C-style character strings. Strings that follow this convention are stored in character arrays and are null terminated. The Standard C library provides a set of functions, that operate on C-style strings. These function are defined in the cstring header, which is the C++ version of the C header string.h. | C-Style Character String Functions | Description | | :--- | :--- | | strlen\(p\) | Return the length of p, not counting the null. | | strcmp\(p1, p2\) | Compares p1 and p2 for equality. Returns 0 if p1 == p2, a positive value if p1 &gt; p2, a negative value if p1 &lt; p2. | | strcat\(p1, p2\) | Appends p2 to p1. Returns p1. | | strcpy\(p1, p2\) | Copies p2 into p1. Returns p1. | ### 3.5.3 Interfacing to Older Code The name c\_str indicated that the function returns a C-style character string. The is, it returns a pointer to the beginning of a null-terminated character array that holds the same data as the characters in the string. The vector can be used an array to initialise. ```cpp int init_arr[] = {0, 1, 2, 3}; vector<int> ivec(begin(init_arr), end(init_arr)); ``` ## 3.6 Multidimensional Arrays Strictly speaking, there are no multidimensional arrays in C++. What are commonly referred to as multidimensional arrays are actually arrays of arrays. ```cpp int ia[3][4]; // array of size 3; each element is an array of ints of size 4 int ia[3][4] = { // three elements; each elementis an array of size 4 {0, 1, 2, 3}, // initialsers for rwo indexed by 0 {4, 5, 6, 7}, // initialsers for rwo indexed by 1 {8, 9, 10, 11} // initialsers for rwo indexed by 2 }; // equivalent initialisation without the optional nested braces for each row int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // using a Range for with Multidimensional arrays for (auto row : ia) for (auto col : row) ... int *ip[4]; // array of pointers to int int (*ip)[4]; // pointers to an array of four ints // Type Aliases using int_array = int[4]; typedef int int_array[4]; ```