为了正确回答您的问题,请了解行主序,这是多维数组在C中存储的方式。
Wikipedia article有点简略,但其中一个可能更清晰:
http://webster.cs.ucr.edu/AoA/Windows/HTML/Arraysa2.html
http://archive.gamedev.net/archive/reference/articles/article1697.html
http://www.ibiblio.org/pub/languages/fortran/append-c.html
这里还有一个相关的问题
在Stack Overflow上。
回答你的问题,假设你知道行主序存储的工作原理:
int A[5][2][3]
声明了一个连续的内存区域,长度为 5*2*3 个整数:五个大小为两个大小为三个整数的数组。这些数组在线性内存中相邻存储。
&A[0][0][0] == A
&A[0][0][1] == A+1
&A[0][1][0] == A+(1*3)
&A[3][1][2] == A+(3*(2*3))+(1*3)+2
A[1]
技术上不是指针,而是一个数组。它是一个 int [2][3]
数组。但我发现考虑 A[5][2][3]
是一个长度为 30 的扁平内存区域比考虑数组更清晰易懂。
A[0][0][0] is the first integer in that region.
A[0][0][1] is the second integer.
A[0][0][2] is the third integer.
A[0][1][0] is the fourth integer in this flat region.
A[0][1][1] is the fifth integer.
And so on until A[1][0][0] is the eleventh integer.
因此,
A [1] [0] [0]
的地址比
A [0] [0] [0]
多十个整数;也就是说,
&A [1] [0] [0] - &A [0] [0] [0] == 10
。因为 C 语言在数组和指针之间的区别上非常宽松,所以当您在表达式中使用
A [1]
时,它会被解释为地址,即使它实际上意味着“一个由五个数组组成的数组,每个数组又由两个包含三个整数的数组组成”,而这又是“一个由两个包含三个整数的数组组成”的数组。
结果是A [1]
并不是存储指针,它本身就是一个指针。您的多维数组中从&A [0] [0] [0]
到&A [5] [2] [3]-1
的所有内存地址都存储了一个整数。
您在第二点和第三点中考虑的是指向数组的指针(arrays of pointers to arrays),那是另外一回事。
这个问题最好用图片来解释,因此你应该找一本适当的关于C数组的教材或文章。
通常,在学习C语言中指针和数组时,我建议您暂时忘记语言本身,并假装自己是Dennis Ritchie在一台只有56kb平面RAM的PDP-11计算机上发明C语言。拿一张大的方格纸,连续编号每个单元格,假装它代表你的RAM,每个单元格都是一个字节,你可以用铅笔和纸来进行指针运算。
C语言就是在那种环境下发明的,了解其起源将使现代语言更加合理。
顺便提一下,当我尝试写这个答案时,Stack Overflow的标记语言反复更改并破坏了上面我的数组示例中的索引。因此,如果你看到那里的任何数字似乎超出了它们的数组范围,那是编辑器引入的错误。