定义和初始化内置数组
数组的声明形式如 a[d],其中a是数组的数组的名字,d是数组的维度,维度说明数组中元素的个数,维度必须是一个常量表达式且大于0:
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时正确,否则错误
- 定义数组的时候必须指定数组的类型,不允许用auto关键字由初始值的列表推断类型
- 数组的元素应为对象,不存在引用的数组
显式初始化数组元素
- 对数组元素进行列表初始化,此时允许忽略数组的维度。
- 声明时没有指明维度,编译器会根据初始值的数量计算并推测出来。
- 指明了维度,初始值的数量不应该超出指定的大小
- 维度比提供的初始值数量大,则用提供的初始值初始化靠前的元素,剩下的元素被初始化成默认值。
const unsigned sz = 3; int ial[sz] = { 0,1,2 };//含有3个元素的数组,元素值分别式0,1,2 int a2[] = {0,1,2};//维度是3的数组 int a3[5] = {0,1,2};//等价于a3[]={0,1,2,0,0}; string a4[3] = {"hi","bye"};//等价于a4[] = {"hi","bye",""} int a5[2] = {0,1,2};//错误:初始值过多
字符数组的特殊性
用字符串字面值对字符串数组初始化,字符串字面值的结尾空字符也会像字符串的其他字符一样被拷贝到字符数组中:
char a1[] = {'C','+','+'};//列表初始化,没有空字符 char a2[] = { 'C','+','+','\0' };//列表处死话,含有显式的空字符 char a3[] = "C++";//自动添加表示字符串结束的空字符 const char a4[6] = "Daniel";//错误:没有空间可存放空字符!
不允许拷贝和复制
不能讲数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值:
int a[] = { 0,1,2 };//含有3个整数的数组 int a2[] = a;//错误:不允许使用一个数组初始化另一个数组 a2 = a;//错误:不能把一个数组直接赋值给另一个数组
理解复杂的数组声明
可以定义一个存放指针的数组,数组本身就是对象,允许定义数组的指针及数组的引用:
int* ptrs[10];//ptrs是含有10个整型指针的数组 int& refs[10] =/*?*/;//错误:不存在引用数组 int (*Parray)[10] = &arr;//Parray指向一个含有10个整数的数组 int(&arrRef)[10] = arr;//arrRef引用一个含有10个整数的数组
对修饰符的限制并没有特殊限制:
int* (&array)[10] = ptrs;//array是数组的引用,该数组含有10个指针
Note:理解数组声明的含义,最好的办法是从数组的名字开始按照由内向外的顺序阅读。