C++ Primer 笔记九 多维数组
通常所说的多维数组,其实是数组的数组。
int a[3][4]; // 大小为3的数组,每个元素是大小为4的数组
// 大小为10的数组
// 每个元素是大小为20的数组
// 这些数组的元素是含有30个整数的数组
int a1[10][20][30];
多维数组的初始化
int ia[2][3] = {{2, 5, 8}, {8, 9, 10}};
等价于
int ia[2][3] = {2, 5, 8, 8, 9, 10};
可以显示地初始化每行的首元素,其他未列出的元素执行默认初始化
int ia[2][3] = {{2}, {8}};
显示地初始化第一行,其他默认初始化
int ia[2][3] = {2, 5, 8, 8};
多维数组元素的访问
可以使用下标运算符来访问多维数组的元素:
int iarr[2][3][4] = {0};
int iarr1[3][2];
// 使用iarr的第一个元素为iarr1的最后一行最后一个元素赋值
iarr1[2][1] = iarr[0][0][0];
// 把row绑定到iarr的第二个3元素数组上
int (&row)[3] = iarr[1];
程序中经常用多层嵌套的 for
循环来访问多维数组的元素:
// 示例:使用多层嵌套的for循环输出一个二维数组
// example.cc
#include <iostream>
int main() {
const unsigned rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt];
for (size_t i = 0; i != rowCnt; ++i) {
for (size_t j = 0; j != colCnt; ++j) {
ia[i][j] = i * colCnt + j;
std::cout << ia[i][j] << "\t";
}
std::cout << std::endl;
}
return 0;
}
$ ./example.out
0 1 2 3
4 5 6 7
8 9 10 11
也可以使用范围 for
来处理多维数组:
// 示例2:使用范围for输出一个二维数组
// example2.cc
#include <iostream>
int main() {
const unsigned rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt];
int cnt = 0;
// 因为要改变数组的元素,所以控制变量声明为引用类型
// 外层数组的每一个元素
for (auto &row : ia) {
// 内层数组的每一个元素
for (auto &col : row) {
col = cnt;
++cnt;
std::cout << col << "\t";
}
std::cout << std::endl;
}
return 0;
}
$ ./example2.out
0 1 2 3
4 5 6 7
8 9 10 11
事实上,使用范围 for
处理多维数组,除了最内层的循环外,其他所有的控制变量都应该是引用类型。
一个错误的例子:
for (auto row : ia) { // row 的类型为 int*
// 下面操作将引发错误
// note : mismatched types ‘_Tp [_Nm]’ and ‘int*’
for (auto col : row) {
// ...
}
}
编译器初始化 row 时会自动将这些数组形式转换成数组内首元素的指针,因此 row 的类型是 int* 。一个正确的例子:
// 将外层循环的控制变量声明成引用类型
for (const auto &row : ia) {
for (auto col : row) {
cout << col << endl;
}
}
指针和多维数组
由多维数组名转换得来的指针实际上是指向第一个内层数组的指针(多维数组是数组的数组):
int ia[3][4];
int (*p)[4] = ia; // p指含有4个整数的数组,其中圆括号'()'必不可少
p = &ia[2]; // p指向ia的尾元素
C++11允许通过 auto
和 decltype
来简化声明:
// 使用auto
for (auto p = ia; p != ia + 3; ++p) { // p是一个int[4] *类型
// 解引用p得到指向内层数组首元素的指针,q是一个int*类型
for (auto q = *p; q != *p + 4; ++q) {
std::cout << *q << ' ';
}
std::cout << std::endl;
}
// 使用decltype
decltype(ia) p; // p是一个int[3][4]
可以使用标准库函数 begin
和 end
来简化指针运算:
// p指向ia的第一个数组
for (auto p = std::begin(ia); p != std::end(ia); ++p) {
// q指向内层数组的首元素
for (autor q = std::begin(*p); q != std::end(*p); ++q) {
std::cout << *q << ' ' ;
}
std::cout << std::endl;
}
还可以使用类型别名来简化多维数组的指针:
using int_arr = int[4]; // 声明int_arr为int[4]的别名
// 等价于:
typedef int int_arr[4];
for (int_arr *p = ia; p != ia + 3; ++p) {
for (int *q = *p; q != *p + 4; ++q) {
std::cout << *q << '\t';
}
std::cout << std::endl;
}
好好学习天天向上~(๑•̀ㅂ•́)و✧