三位数组:int a[2][2][3]

表达式 步长
&a + 1 sizeof(int) * 2 * 2 * 3
a + 1a[1] sizeof(int) * 2 * 3
*a + 1a[0] + 1a[0][1] sizeof(int) * 3
**a + 1a[0][0] + 1a[0][0][1] sizeof(int)

当对一个数组(以上述a为例)取地址时,得到相当于这个数组的指针,即:

1
int ****ptr = &a;

相当于一个 a[2][2][3] 的指针,步长为 sizeof(int) * 2 * 2 * 3

默认 a[2][2][3]a + 1 的步长是除第一个下标外的数组字节,即不管第一个下标 2。每次对 a* 解引用,或者加上数组 [x],步长依次除以前面一个下标长度。

例如 b[5]b + 1 的步长就是 sizeof(int),和第一个下标长度 5 无关。


测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
// printf("%d\n", sizeof(int)); // 4
int a[2][2][3] = {{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}};
int *ptr = (int *)(&a + 1); // 步长=2*2*3*int
printf("%d %d\n", *(int *)(a + 1), *(ptr - 1)); // 7 12

printf("%p %p %p %p\n", a, a + 1, &a + 1, *a + 1); // 0, +8, +48, +4
printf("%p %p %d %d\n", a, ptr, **a, *ptr); // 0, +48, ?, ?
printf("%d %d\n", *(*(*(a + 1) + 0) + 0), a[1][0][0]); // 7, 7
printf("%d %d\n", *(*(*(a + 0) + 0) + 1), a[0][0][1]); // 2, 2
printf("%d %d\n", *(*(*(a + 1) + 0) + 2), a[1][0][2]); // 9, 9
}