繁体   English   中英

c程序输出说明

[英]c program output explanation

我在网上某处找到了这段代码。 程序的输出为string string string有人可以解释一下为什么为什么第一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维数组(array of array of array),因此*aa**a都引用相同的地址。 对于前两个, printf()的类型不正确,但是在所有情况下都将其解释为纯char *字符串。 如果您在编译器上打开警告,则应该看到一些有关格式字符串和类型不匹配的信息。

请记住, *aa[0]**aa[0][0] 这样可以更容易理解为什么他们引用相同的地址。

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

这是不确定的行为; 不要做

让我们看看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]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

最后,请提一下建议,以这种方式进行编码。 如果您足够聪明,请仅通过指针执行所有操作。 但是它更容易出错。 因此,尽管基础层几乎可以互换使用指针和数组,但是您还是要坚持自己的初衷。 如果可以用手操纵东西,则将其视为指针。 如果您想通过索引进行更严格的操作,则将它们视为数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM