C++ Study Notes (3) - Strings, Vectors and Arrays
namespace using declaration
The purpose of C++ namespaces is to prevent name collisions. In order to use members of a namespace, using
declarations can be used. With the using
declaration, there is no need for a special prefix. using
The form of the declaration is as follows
using namespace::name;
- Each name requires a separate
using
declaration. - Header files should not contain
using
declarations, because the contents of the header file are copied to all files that reference it, and if there is ausing
declaration in the header file, then every file that uses the header file will have the declaration. may cause name conflicts
Note : Namespaces require deep learning
Standard library type string
Standard library types string
represent variable-length sequences of characters, and the string type is defined in the namespace std
.
Defining and initializing string objects
- Direct initialization: initialization without an equals sign
- Copy initialization: Use the equal sign to
=
initialize a variable, and the compiler copies the initial value on the right side of the equal sign to the newly created object.
Note : Direct initialization and copy initialization require deep learning
operations on string objects
In addition to defining how to initialize its objects, classes also define what the objects can do.
If there is a
size()
function in the expression, don't useint
the type anymore, because thesize
function returns thestring
matching type of the classstring::size_type
, a value of an unsigned type, and mixing sumsint
canunsigned
cause problems.The standard library allows character literals and string literals to be converted into
string
objects, that is, they can be mixed and used in one statement, but it must be ensured that at least one of the operands on either side of each addition operator isstring
string s1 = "hello", s2 = "world"; string s3 = s1 + ", " + s2 + '\n';
For historical reasons, and for
C
compatibility, string literals in C++ are notstring
objects of standard library types. Remember, string literalsstring
are not of the same type as string literals.
Manipulate characters in string objects
We often need to deal string
with characters in objects separately, and the cctype
header file defines a set of standard library functions to handle this part of the work
The C language header file is like
name.h
, C++ names itcname
, C++ programs should use the latter, because the name of the standard library can always be found in the namespacestd
, if the.h
header file is used, it cannot be found.C++11 can use the range
for
statement to operate onstring
each character of the object. If you want to changestring
the value of the character in the formation, you must define the loop variable as a reference type.for(auto &c: str) c = toupper(c); // c 是一个引用,因此赋值语句将改变 s 中字符的值
Standard library type vector
Standard library types vector
represent collections of objects, where all objects are of the same type, also known as containers
vector
is a template not a type,vector
the type generated by must containvector
the type of the element in, e.g.vector<int>
vector
Can hold most thank-type objects as elements, but cannot be references, because references are not objects, elements can also bevector
Defining and initializing vector objects
The following table lists vector
common ways to define objects
List initialization:
vector
The method provided by the new C++11 standard to assign initial values to the elements of an object.Copy initialization: even
=
when used, only one initial value can be providedIf you provide an in-class initializer, you can only use copy-initialization or initialize with curly braces
If a list of initial element values is provided, the initial value can only be initialized by placing the initial value in curly braces, not parentheses.
vector<int> v1(10); // v1 有 10 个元素,每个值都为0 vector<int> v2{10}; // v2 有 1 个元素,该元素的值是10 vector<int> v3(10, 1); // v3 有 10 个元素,每个的值都是1 vector<int> v4{10, 1}; // v4 有 2 个元素,值为 10 和 1 // 若花括号提供的值不能用来列表初始化,则考虑用值构造 vector 对象 vector<string> v5{"hi"}; // 列表初始化,v5 有一个元素 vector<string> v6("hi"); // 错误:不能使用字符串字面值构建 vector 对象 vector<string> v7{10}; // v7 有 10 个默认初始化的元素 vector<string> v8{10, "hi"}; // v8 有 10 个值为 "hi" 的元素
The last four statements above all use curly braces except the second, but only v5 is list-initialized. To be list-initialized, the value in the curly braces must be of the same type as the element.
Other vector operations
vector
Objects andstring
their subscript operators can be used to access existing elements, not to add elements- The body of a range
for
statement should not change the size of the sequence it traverses
Introduction to Iterators
The iterator provides indirect access to the object, the object is the element in the container or string
the character in the object, the iterator is valid and invalid, the valid iterator points to an element, or the next position of the tail element in the container, other All cases are invalid.
use iterator
- Types that have iterators all have members that return iterators, such as a
end
member that returns尾元素的下一位置
an iterator to a container, also known as尾后迭代器
. If the container is empty, the same iteratorbegin
isend
returned as it is, both are tail-end iterators
- try to use !=
not <
, because all standard library container iterators define ==
and !=
, but most do not define <
operators
Standard library types generally use
iterator
andconst_iterator
to represent iterator typesvector<int>::iterator it; // it 能读写 vector<int> 的元素 vector<int>::const_iterator it3; // it3 只能读元素,不能写元素
If the
vector
orstring
object is a constant, you can only useconst_iterator
For any loop body that uses an iterator, do not add elements to the container to which the iterator belongs
iterator operations
- The result type of the subtraction of two iterators is
difference_type
a signed integer named, representing the distance between the two iterators
array
Arrays are vector
similar, but the size is fixed.
Defining and initializing built-in arrays
The dimensions of the array should be known at compile time, i.e. the dimension must be a constant expression
unsigned cnt = 42; // 不是常量表达式 constexpr unsigned sz = 42; // 常量表达式 int arr[10]; // 含有 10 个整数的数组 int *parr[sz]; // 含有 42 个整型指针的数组 string bad[cnt]; // 错误: cnt 不是常量表达式 string strs[get_size()]; // 当 get_size 是 constexpr 时正确,否则错误
By default, the elements of the array are default-initialized and contain undefined values if defined inside the function body
When defining an array, the type of the array must be specified, and the use of
auto
keywords to infer the type is not allowedint *ptrs[10]; // ptrs 是含有 10 个整型指针的数组 int &refs[10] = /* ? */; // 错误:不存在引用的数组 int (*parray)[10] = &arr; // Parray 指向一个含有 10 个整数的数组 int (&arrRef)[10] = arr; // arrRef 引用一个含有 10 个整数的数组
When accessing array elements using array subscripts, the type is
size_t
, a machine-dependent unsigned type, in thecstdef
header file.
pointers and arrays
When using an array, the compiler generally converts it to a pointer
In most expressions, using an object of type array is actually using a pointer to the first element of the array
string nums[] = {"one", "two", "three"}; // 数组的元素是 string 对象 string *p = &nums[0]; // p 指向 nums 的第一个元素 string *p2 = nums; // 同上 auto nums2(nums); // nums2 是一个 string 类型指针,指向 nums 的第一个元素,等价于 auto nums2(&nums[0]) decltype(nums) nums3 = {"three", "two", "one"}; // nums3 是一个含有三个string类型对象的数组
The new C++11 standard introduces two functions named
begin
andend
, which are similar to the function of the same name of the container. Thebegin
function returns a pointer to the first element of the array, and theend
function returns a pointer to the next position of the end element of the array.int ia[] = {0, 1, 2, 3, 4, 5}; int *beg = begin(ia); // 指向 ia 首元素的指针 int *last = end(ia); // 指向 arr 尾元素的下一位置的指针
The result of two pointer construction is the distance between them, the result is
ptrdiff_t
the signed standard library type, definedcstddef
inThe subscript used in the standard library type qualification must be an unsigned type, but the built-in subscript operator does not have this requirement, that is, the built-in table operator can be negative.
C-style strings
A string literal is an instance of a generic structure, which is a C-style string inherited from C. It is customary for strings to be stored in character arrays and terminated by a null character.\0
The above functions are not responsible for validating their string parameters (for example, if the string is not null terminated, an error will be reported)
C++ provides a set of functions for connecting C++ programs that use the C interface;
Allows C-style strings to initialize
string
objects, but not vice versa, but you can usestd::c_str
functions to get C-style strings and return the result pointer, the type isconst char *
vector
Allow objects to be initialized with arrays
int int_arr[] = {0, 1, 2, 3, 4, 5}; vector<int> ivec(begin(int_arr), end(int_arr));
Multidimensional Arrays
Strictly speaking, C++ does not have multi-dimensional arrays. Usually, the multi-dimensional arrays are actually arrays of arrays.
int ia[3][4] = {{0}, {4}, {8}}; // 显示的初始化每行的首元素
int ix[3][4] = {0, 3, 6, 9}; // 显示的初始化第一行,其他元素执行值初始化
When working with multidimensional arrays using range
for
statements, all but the innermost loop's control variables should be reference types.for (auto row : ia) for(auto col : row)
As shown above, since
row
it is not a reference type, the compilerrow
will automatically convert these elements in the form of an array into pointers to the elements in the array during initialization. Suchrow
a type isint *
, so the inner loop will be illegal.
Epilogue
string
and vector
are the two most important standard library types. string
An object is a variable-length sequence of characters, vector
an object is a container for a group of objects of the same type
Iterators allow indirect access to objects in the container. For string
objects and vector
objects, elements can be accessed through iterators or moved through elements.
Arrays and pointers to array elements implement standard library types string
and vector
similar functionality at a lower level. Generally speaking, you should prefer the types provided by the standard library, and then consider the low-level alternatives arrays or pointers built into the C++ language.