让我们看看char a[2][3][3]
在内存中是如何布局的。在我的机器上是这样的:
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00
0x7fffffffe228: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffe230: 0x00 0x00
这是很自然的,因为所有数组实际上都是线性的。这些维度意味着什么,与数组索引(如a[i][j][k]
. 但从内存的角度来看,这只是一种计算基地址偏移量的棘手方法。
现在因为您已将其定义为 3 维数组,您可能想知道 C 在初始化后将如何处理此数组:
{{{0x73, 0x74, 0x72}, {0x69, 0x6e, 0x67}, {0x0, 0x0, 0x0}}, {{0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}}}
现在让我们看看我们这里有什么......
调用 Printf 以打印字符串并通过地址传递。所以 printf 会做的是获取那个地址,并尝试直到它看到一个 null
每次调用print
同一件事,因为:
(gdb) x/10xb **a
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00
0x7fffffffe228: 0x00 0x00
(gdb) x/10xb *a
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00
0x7fffffffe228: 0x00 0x00
(gdb) x/10xb a
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00
0x7fffffffe228: 0x00 0x00
最后一句忠告,这样做编码。如果您足够聪明,请仅凭指针做所有事情。但它更容易出错。因此,尽管底层将几乎可以互换地处理指针和数组,但你还是坚持你已经开始的。如果可以用手操作东西,请处理指针之类的东西。如果您想通过索引进行更严格的操作,请处理数组之类的东西。