本节书摘来自异步社区出版社《C和C++代码精粹》一书中的第2章,第2.11节,作者: 【美】Chuck Allison,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.11 更高深的内容
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} }
}
};
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。