阅读复杂数组声明时,建议由内向外阅读;
int *ptrs[10]; // ptrs是一个含有10个整型指针的数组
int &refs[10] = /* ? */; // 错误,不存在引用的数组
int (*Parray)[10] = &arr; // Parray指向一个含有10个整数的数组
int (&arrRef)[10] = arr; // arrRef引用含有一个含有10个整数的数组
*Parray 意味着 Parray 是一个指针;
&arrRef 意味着 arrRef 是一个引用;
int *(&arry)[10] = ptrs; // arry 是数组的引用,该数组含有10个指针;
当使用数组下标的时候,通常将其定义为 size_t 类型;size_t 是一种机器相关的无符号类型,其足够大能表示内存中任意对象的大小;
对数组的元素使用取地址符能得到指向该元素的指针;
在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针;
当使用数组作为一个 auto 变量的初始值时,推断得到的类型是指针而不是数组;
int ia[] = {0, 1, 2, 3}
auto ia2(ia);
ia2 = 42; // 错误, ia2是一个指针
auto ia3(&ia[0]); // ia3 的类型是 int*
当使用 decltype 关键字时上述转换不会发生,decltype(ia) 返回的类型是由10个整数构成的数组;
decltype(ia) ia3 = {0, 1, 2, 3}
ia3[1] = i; // 将 i 的值赋给 ia3 的一个元素
C++11 新标准引入了两个名为 begin 和 end 的函数,可用于表示数组的首元素指针和尾后指针;
尾后指针不能进行解引用和递增操作;
int ia[] = {0, 1, 2, 3}
int *beg = begin(ia); // beg表示ia首元素的指针
int *last = end(ia); // end表示ia最后一个元素的下一个位置的指针(尾后指针)
constexpr size_t sz = 5;
int arr[sz] = {1, 2, 3, 4, 5}
auto n = end(arr) - begin(arr);
上述代码中,n的值为5,其类型是 ptrdiff_t;
两个指针相减的结果的类型是ptrdiff_t,其是一种标准库类型,与 size_t 同样定义在 cstddef 头文件中;
C风格的字符串存放在字符数组中,以空字符结束(‘\0’),即字符串最后一个字符后面还有一个空字符('\0');
对于C风格的字符串,C语言标准库提供了以下函数用于操作字符串:
strlen(p); // 返回p的长度,空字符不计算在内
strcmp(p1, p2); // 比较p1和p2的相等性
strcat(p1, p2); // 将p2附加到p1之后,返回p1
strcpy(p1, p2); // 将p2拷贝给p1,返回p1
需要注意的是传入此类函数的指针必须指向以空字符作为结束的数组:
char ca[] = {'A', 'B', 'C'};
cout << strlen(ca) << endl; // 错误,ca没有以空字符结束
在 C++ 中,允许使用以空字符结束的字符数组来初始化 string 对象或为 string 对象赋值;但不允许用 string 对象直接初始化指向字符的指针,为了完成该功能需要借助 string提供的 c_str() 成员函数;
c_str() 函数的返回值是一个C风格的字符串,即函数的返回结果是一个指针,该指针指向一个以空字符结束的字符数组;
string s("Hello World");
char *str = s; // 错误,不能使用 string 对象直接初始化char*;
const char *str = s.c_str(); // 正确
现代的 C++ 程序应尽量使用 vector 和迭代器,避免使用内置数组和指针;
在 C++ 程序中,多维数组指的是数组的数组;
使用范围 for 语句处理多维数组:
constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt];
size_t cnt = 0;
for(auto &row : ia) // 外层数组
for(auto &col : row){ // 内层数组的每一个元素
col = cnt; // 赋值
++cnt;
}
使用范围 for 语句处理多维数组时,尽管不涉及写的操作,也需要将外层循环的控制变量声明为引用类型,以避免数组被自动转换成指针:
for(const auto &row : ia)
for(auto col : row)
cout << col << endl;