数组
定义和初始化内置数组
数组中的元素个数必须已知,不能使用 auto
推断类型,必须在定义时指定数组类型,数组的元素都是对象,所以不存在引用的数组。
默认情况下,数组元素会被默认初始化,默认初始化会使数组含有未定义的值。
可以对数组元素进行列表初始化,此时可以忽略数组的维度。
字符串数组初始化会自动在末尾添加一个空字符,列表初始化不会自动添加。
不允许用数组对数组进行拷贝和赋值
理解数组声明的含义,最好由内向外阅读。
例子:
int *a[10]; //含有10个整型指针的数组
int &a[10]; //错误,不存在引用的数组
int (*a)[10]; //指向一个含有10个整数的数组
int (&a)[10]; //引用一个含有10个整数的数组
int *(&a) [10]; //引用一个含有10个整型指针的数组
访问数组元素
数组下标是 size_t
类型。(数组使用下标运算符的时候)
数组下标是否在合理范围之内由程序员负责检查,数组下标应该大于等于0且小于数组的大小。
指针和数组
使用数组的时候编译器一般会把它转换为指针。
对数组元素使用取地址符就能得到指向该元素的指针。大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。
例子:
int a[]={1,2,3};// 数组元素是int对象
int *b=&a[0];// b指向a的第一个元素
数组指针也是迭代器。迭代器支持的运算,数组指针全都支持。
数组的特殊性质可以获取数组尾部元素之后的并不存在的元素的地址。
例子:
int a[2]={1,2};
int *b=&a[2]; // 指向尾元素的下一位置的指针
标准库函数 begin 和 end
c++ 11引入的新函数,一个是首元素指针,一个是尾元素下一位置指针。
例子:
int a[]={1,2};
int *b=begin(a); // 指向数组a的首元素
int *c=end(a); // 指向数组a的尾元素的下一位置
在使用下标运算符的时候,编译器会自动转换成指针运算。
例子:
int a[3]={1,2,3};
int b=a[1];
// 编译器会转换成下面的操作
int c=*(a+1);
只要是指向数组中的元素(或者数组中尾元素的下一位置),都可以执行下标运算。
例子:
int a[3]={1,2,3};
int *b=&a[1]; // b指向数组中的第二个元素
int c=b[-1]; // b[-1]等价于*(b-1),也就是数组中的第一个元素
注: 内置的下标运算符的索引值不是无符号类型,可以为负数,只有数组的下标运算符是非负数。
多维数组
多维数组就是数组的数组。
对于二维数组,第一维称为行,第二维称为列。
由内向外阅读有助于理解其真实含义:
int a[3][4]; // 大小为3的数组,每个元素是大小为4的数组
可以用别名来简化多维数组的指针操作
网友评论