数组
数组的引入I
声明
int a //类型:int
int b[10] //类型:int[10]
int b[x]; //error:可变长度数组,variable length array c, c语音支持但是c++不支持
C++数组类型标准:const exp
1.常量,
2.在编译期可以确定
3.可转为size_t,且大于零 //error: int b[3.14]; int b[-1]; int b[0]
初始化
缺省初始化: int b[3];//函数中缺省初始化为随机值,全局域内初始化为0
聚合初始化:
- int b[3] = {1,2,3};
- int b[3] = {1,2}//其中b[2] = 0
- int b[3] = {}; //元素初始化为0
- int b[] = {1,2,3}//自动推导b的类型为 int[3]
- int b[]; //ERROR:需要给出值
- int b[2] ={1,2,3} //ERROR:初始化元素个数要小于类型
注意:
- 不能用auto声明数组:auto b = {1,2,3}; //类型不为int[3]
- 数组不支持复制,数组做右值退化为指针
- int b[] = {1,2,3}; int a[3] = b //ERROR
- int b[] = {1,2,3}; auto a = b // a的类型为int*
- int b[] = {1,2,3}; auto& a = b // a的类型为int(&)[3]
字符串数组具有特殊性
- char str[] = “Hello” //类型为char[6],默认加了’\0’
- char str[] = {‘H’,’e’,’l’,’l’,’o’},//类型为char[5]
数组的引入II
数组的复杂类型:
指针的数组
int a[3]; //a为有三个指针的数组,类型int[3]
int a[3] = {&x,&y,&z};
数组的指针
int (a)[3] = &b; //其中int b[3], a是一个指针,指向int[3]。
数组的引用
int (&a)[3] = b; //数组的引用,其中int b[3]
引用的数组//ERROR,引用只是别名数组中的元素访问
数组元素为左值,作为右值使用时退化为int*
int a[3] = {1,2,3}; auto b = a // b为int*
- a[0]系统先翻译为int*
- 指针也可以使用中括号,如 int* ptr = &x, 则ptr[1] = 2;
- 注意溢出
[]中括号的解释:ptr[n]//对于系统的内建类型,[] = *(ptr + n) 等价与 n[ptr] == ptr[n]
- 注意溢出
从数组到指针
- 大多数情况会产出数组到指针的隐式转换,除了sizeof,de
- 隐式转换后丢失了数组大小信息,编译器无法进行越界检查
- 可以通过声明引用来避免隐式转换int a[3]; int& b = a; //b 为int(&)[3]
上:内存地址,下:保存的值
- 不要用extern指针声明数组
- extern int array[4] //声明连接到其他文件中的定义
- extern int* array; array = [1,2,3] //ERROR,array[0]表示0x20000001地址中的值,该地址不一定存在
- 可以改为extern int array[]; 不确定数组个数时可以这么声明。//不完整类型
- begin,end
- int a[4];
- std::begin(a),std::end(a),//可写
- std::cbegin(a),std::cend(a),//只读
- 不完整类型和auto降级无法使用上述函数
- 指针算数:
- 增加,减少,1~n
- 比较: ==, !=, >=, <=, >, < //建议只用于同一个数组的指针
- 求距离:两个指针相减,//两个指针之间包含的元素个数
- 解引用
- 指针索引
多维数组
类型
int x2[3][4];//x2[0]为int(&)[4]类型
聚合初始化
一层大括号 && 多层大括号
建议多层大括号初始化