本节书摘来自异步社区出版社《C和C++代码精粹》一书中的第2章,第2.11节,作者: 【美】Chuck Allison,更多章节内容可以访问云栖社区“异步社区”公众号查看。
C和C++代码精粹我们可以很自然地得出以下结论:一个三维数组是二维数组的集合。
int a[2] [3] [4]={{{0,1,2,3},{4,5,6,7},{8,9,0,1}}, {{2,3,4,5},{6,7,8,9},{0,1,2,3}}};这个数组的第一个元素是一个“二维数组” a[0](从技术上来说,a[0]是一个由3个含有4个整数的数组的数组),为了使指针与数组名a一致,定义:
int (*p) [3] [4] = a;程序清单2.16是一个应用该指针的程序示例,表2.2是与表2.1相似的三维数组。
表2.1 对于二维数组的数组指针转换
其中十六进制值是相对于a的地址偏移量。
程序清单2.16 说明在三维数组内指向二维数组的指针
// array9.c: 使用一个二维数组指针 #include <iostream> using namespace std; main() { int a[][3][4] = {{{0,1,2,3},{4,5,6,7},{8,9,0,1}}, {{2,3,4,5},{6,7,8,9},{0,1,2,3}}}; int (*p)[3][4] = a; size_t ntables = sizeof a / sizeof a[0]; size_t nrows = sizeof a[0] / sizeof a[0][0]; size_t ncols = sizeof a[0][0] / sizeof a[0][0][0]; cout << "sizeof(*p) == " << sizeof *p << endl; cout << "sizeof(a[0][0]) == " << sizeof a[0][0] << endl; for (int i = 0; i < ntables; ++i) { for (int j = 0; j < nrows; ++j) { for (int k = 0; k < ncols; ++k) cout << p[i][j][k] << ' '; cout << endl; } cout << endl; } } //输出: sizeof(*p) == 48 sizeof(a[0][0]) == 16 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3表2.2 关于三维数组的数组指针转换
表 达 式
其中,十六进制值是相对于a的地址偏移量。
在程序清单2.15和程序清单2.16中的程序表明如何确定一个数组和它所有的子数组的秩(即维数),对于程序清单2.15中的二维数组a,秩是它所包含的行数(一维对象),也就是:
sizeof a /sizeof a[0]从名称上讲,每一个行的秩就是a中每一行的整数的个数(0维对象):
sizeof a[0] /sizeof a[0][0]总的来说,如果a是一个n维数组,那么,a为n−1维对象
sizeof a /sizeof a[0]的集合,a中每一个(n-1)维对象包含n-2维对象
sizeof a[0] /sizeof a[0][0]每一个(n-2)维对象依次包含(n-3)维对象
sizeof a[0][0] /sizeof a[0][0][0]等等,直到每一个一维对象中零维对象的个数为
sizeof a[0][0]…[0] /sizeof a[0][0]…[0][0] {_n_-_1__subscripts_} {_n_-_1__subscripts_}练习2.3
模仿表2.1和表2.2,完成下面四维数组的数组指针转换表:
int a[2][3][4][5] = { { { {0,1,2,3,4},{5,6,7,8,9},{0,1,2,3,4},{5,6,7,8,9} }, { {0,1,2,3,4},{5,6,7,8,9},{0,1,2,3,4},{5,6,7,8,9} } { {0,1,2,3,4},{5,6,7,8,9},{0,1,2,3,4},{5,6,7,8,9} } }, { { {0,1,2,3,4},{5,6,7,8,9},{0,1,2,3,4},{5,6,7,8,9} }, { {0,1,2,3,4},{5,6,7,8,9},{0,1,2,3,4},{5,6,7,8,9} } { {0,1,2,3,4},{5,6,7,8,9},{0,1,2,3,4},{5,6,7,8,9} } } };本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。
相关资源:C和C 代码精粹