c程序输出说明

时间:2012-07-26 13:48:53

标签: c multidimensional-array

我在网上的某个地方找到了这段代码。该程序的输出是 串 串 串 有人可以解释一下为什么第一个secon和第三个printf语句打印相同的输出,即使它们的参数不同?

#include<stdio.h>
int main()
{
char a[2][3][3] = {'s','t','r','i','n','g'};
printf("%s\n", *a);
printf("%s\n", a);
printf("%s\n", **a);
getchar();
return 0;
}

3 个答案:

答案 0 :(得分:8)

由于这是三维数组(数组数组的数组),*aa**a都引用相同的地址。对于前两个类型,printf()的类型不正确,但在所有情况下都将被解释为平坦的char *字符串。如果你打开编译器上的警告,你应该看到一些格式字符串和类型不匹配。

请注意,*aa[0]类似,**aa[0][0]类似。这可能会让他们更容易理解为什么他们引用相同的地址。

答案 1 :(得分:2)

您将char (*)[3]char (*)[3][3]视为char *。由于它们指向相同的地址,并且(在这种情况下)它们具有相同的内存中表示,因此它们的读取方式与指向该地址的char *相同。

这是未定义的行为;不要这样做。

答案 2 :(得分:1)

让我们了解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]等数组索引很方便。但从内存的角度来看,它只是一种从基地址计算偏移量的棘手方法。

现在因为你已经将它定义为三维数组,你可能想知道C在初始化后如何处理这个数组:

{{{0x73, 0x74, 0x72}, {0x69, 0x6e, 0x67}, {0x0, 0x0, 0x0}}, {{0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}}}

现在让我们看看我们在这里有什么......

调用Printf来打印刺痛并传递地址。那么printf会做什么,就是抓住那个地址,然后尝试直到它看到空

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

最后一句建议,就是这样编码。如果你足够聪明,只需按指针做一切。但它更容易出错。因此,虽然底层将几乎可以互换地处理指针和数组,但是你坚持使用你已经开始的东西。如果可以用手操纵东西,可以像指针一样处理。如果你想通过索引进行更严格的操作,可以对待像数组这样的东西。