当一个数组的元素仍然是数组时,通常使用两个维度来定义它:一个维度表示数组本身大小,另外一个维度表示其元素大小:
int ia[3][4];//大小为3的数组,每个元素是含有4个整数的数组 //大小为10的数组,它的每个元素都是大小为20的数组 //这些数组的元素是含有30个整数的数组 int arr[10][20][30] = { 0 };//将所有元素都初始化为0
多维数组的初始化
允许使用花括号括起来的一组值初始化多维数组:
int ia[3][4] = {//三个元素,每个元素都是大小为4的数组 {0,1,2,3},//第1行的初始值 {4,5,6,7},//第2行的初始值 {8,9,10,11}//第3行的初始值 };
内层嵌套着的花括号并非必需的:
//没有标识每行的花括号 int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
在初始化多维数组时也并非所有元素的值都必须包含在初始化列表之内:
//显式地初始化每行地首元素 int ia[3][4] = { {0},{4},{8} };
其他未列出的元素执行默认初始化,这一过程和一维数组。
//显式地初始化第1行,其他元素执行值初始化 int ix[3][4] = {0,3,6,9};
初始化的是第一行的4个元素,其他元素被初始化为0。
多维数组的下标引用
- 如果表达式含有的下标运算符数量和数组的维度一样多,该表达式的结果将是给定类型的元素
- 如果表达式含有的下标运算符数量比数组的维度小,则表达式的结果将是给定索引处的一个内层数组:
//用arr的首元素为ia最后一行的最后一个元素赋值 ia[2][3] = arr[0][0][0]; int(&row)[4] = ia[1];//把row绑定到ia的第二个4元素数组上
两层嵌套的for循环来处理多维数组的元素:
constexpr size_t rowCnt = 3, colCnt = 4; int ia[rowCnt][colCnt];//12个未初始化的元素 //对于每一行 for (size_t i = 0; i != rowCnt; ++i) { //对于每一列 for (size_t j = 0; j != colCnt; ++j) { //将元素的位置索引作为它的值 ia[i][j] = i * colCnt + j; } }
使用范围for语句处理多维数组
//使用范围for语句处理多维数组 size_t cnt = 0; for(auto &row:ia)//对于外层数组的每一个元素 for (auto &col : row) {//对于内层数组的每一个元素 col = cnt;//将下一个值赋给该元素 ++cnt;//将cnt加1 }
避免数组被自动转成指针:
for (const auto& row : ia)//对于外层数组的每一个元素 for (auto col : row)//对于内层数组的每一个元素 cout << col << endl;
不用引用类型,遵循如下形式:
for(auto row:ia) for(auto col:row)
row不是引用类型,编译器初始化row时会自动将这些数组形式的元素转换成指向该数组内首元素的指针,得到row的类型就是int*,内层的循环就不合法了。
指针和多维数组
多维数组名转换得来得指针实际上是指向第一个内层数组的指针:
int ia[3][4];//大小为3的数组,每个元素是含有4个整数的数组 int(*p)[4] = ia;//p指向含有4个整数的数组 p = &ia[2];//p指向ia的尾元素
在上述声明中,圆括号必不可少:
int *ip[4];//整型指针的数组 int(*ip)[4];//指向含有4个整数的数组
通过使用auto或decltype就能尽可能地避免在数组前面加上一个指针类型了:
//输出ia中每个元素地值,每个内层数组各占一行 //p指向含有4个整数的数组 for (auto p = ia; p != ia + 3; ++p) { //q是指向4个整数数组的首元素,也就是说q指向一个整数 for (auto q = *p; q != *p + 4; ++q) cout << *q << ' '; cout << endl; }
使用标准库函数begin和end实现同样的功能:
//p指向ia的第一个数组 for (auto p = begin(ia); p != end(ia); ++p) { //q指向内层数组的首元素 for (auto q = begin(*p); q != end(*p); ++q) { cout << *q << ' ';//输出q所指的整数值 cout << endl; } }
类型别名简化多维数组的指针
using int_array=int[4];//新标准下类型别名的声明 typedef int int_array[4];//等价的typedef声明 //输出ia中每个元素的值,每个内层数组各占一行 for (int_array *p = ia; p != ia + 3; ++p){ for (int* q = *p; q != *p + 4; ++q) cout << *q << ' '; cout << endl; }