数组也是一个存放对象的容器,只不过,他是定长的,且访问其中的元素需要通过元素的位置。
数组是一种复合类型。
内置数组的定义和初始化:
初始化方式分为两种:默认初始化和列表初始化。Type name[size] = {a,b,c}
因为维度也是数组类型的一部分,在编译时应该是已知的,所以数组的维度必须是一个常量表达式。(常量表达式在编译时已知结果)
定义数组的时候必须指定数组的类型,不允许使用auto关键字由初始值的列表推断数组类型。
和内置类型的变量一样,如果在函数内部定义了某种内置类型的数组,那么默认初始化会令数组含有未定义的值。
如果使用字符串字面值初始化一个数组,结尾的空字符也会被拷贝到数组中。
不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值(或许是因为会把数组名当做一个指针)
理解数组的声明时,最好由数组的名字开始由内向外的阅读。(特别是声明一个数组的指针或引用时,记得加括号)
数组的下标:
数组下标的类型是size_t(机器相关的无符号型)
注意下标越界问题。
指针和数组:
在很多用到数组名字的地方,编译器会将其替换为一个指向数组首元素的指针。
特别的:当使用数组作为一个auto变量的初始值时,得到的类型是一个指针而不是数组;
但,使用decltype关键字时上述转换不会发生,返回的类型是一个数组。(我decltype大哥就是直)
指向数组元素的指针其实就相当于容器的迭代器,它有vector迭代器的所有操作。
同样的,在数组中我们可以使用begin和end来获取指向首元素的指针和尾后元素的指针,不过这两个标准库函数并非成员函数,所以要把数组作为这两个函数的参数。
只要指针指向的是数组中的元素,或者尾后元素,都可以执行下标运算。:
int ia[] = {0,2,4,6,8}; int *p = &ia[2]; //p指向数组的第三个元素 int j = p[1]; //等价于*(p+1) int k = p[-2]; //等价于*(p-2)
C风格字符串:
C风格字符串不是一种类型,而是存放在数组里(没明白……)
string的c_str成员函数:返回一个指向与string相同的字符数组的指针。指针的类型是 const char*。如果string对象改变了,这个字符数组也跟着改变。(没太搞懂什么时候要用到string改变之前的字符数组。)
多维数组:
使用范围for语句处理多维数组,除了最内层的循环外,其他所有的控制变量都应该是引用类型。
因为多维数组的第二层依然是一个数组,如果控制变量不是引用类型,则会是一个指针。
定义多维数组的指针时,因为多维数组的首元素其实是一个数组,所以指针其指向的是一个数组:
int a[3][4]; int *p[4]=a;
本部分留下的问题:
数组是单纯的不能给数组初始化,还是就是不能拷贝?如果不能拷贝,C风格字符串怎么算?