多维数组 (multi-dimensional C-style array)#

布局#

多维数组实际上仍然是一维数组, 只是数组的元素是数组.

例如 int marix[3][4], 阅读顺序应该是 matrix[3]-matrix[3][4]-int matrix[3][4] (复杂声明的阅读方法), 它是一个长度为 3 的数组, 数组中的元素是长度为 4 的数组, 而这个内部数组的元素是 int.

10: 0 1 2 3  // 每个元素是一个长度为 4 的数组
21: 0 1 2 3
32: 0 1 2 3
1int matrix[3][4] = {};
2
3for (int i = 0; i < 3; ++i) {
4  for (int j = 0; j < 4; ++j) {
5    std::cout << matrix[i][j] << ' ';
6  }
7  std::cout << '\n';
8}

数组很容易隐式类型转换为指向首元素的指针#

由于它实际仍然是一维数组, 只有这个最外层数组会隐式类型转换为首元素的指针.

1int matrix[3][4] = {};
2auto value = matrix;
3sizeof(value) == sizeof(int (*)[4]);  // 首元素的指针: 指向长度为 4 的 int 数组的指针

传参#

多维数组的传参则由它的布局有多种方法.

直接传递#

按之前一维数组的理解进行直接传递.

 1void print(int (*matrix)[4], int size) {
 2  for (int i = 0; i < size; ++i) {
 3    for (int j = 0; j < 4; ++j) {
 4      std::cout << matrix[i][j] << ' ';
 5    }
 6    std::cout << '\n';
 7  }
 8}
 9
10int matrix[3][4] = {};
11print(matrix, 3);

但这样做限制了内部数组的长度必须是 4.

展平布局传递#

另一种方式是, 我们可以将它的布局展平, 认为是 int 的一维数组.

10       1       2
2↓       ↓       ↓
30 1 2 3 0 1 2 3 0 1 2 3
 1void print(int* array, int row_size, int column_size) {
 2  for (int i = 0; i < row_size; ++i) {
 3    for (int j = 0; j < column_size; ++j) {
 4      std::cout << array[column_size * i + j];
 5    }
 6    std::cout << '\n';
 7  }
 8}
 9
10int matrix[3][4] = {};
11print(&matrix[0][0], 3, 4);

提示

反过来说, 那我们也能直接将一维数组当作多维数组.

1void print(int* array, int row_size, int column_size);
2
3int matrix[12] = {};
4print(&matrix[0], 3, 4);