无法理解这个C片段的输出

时间:2011-01-07 17:45:50

标签: c printf

在以下代码中,行为是否未定义?

#include<stdio.h>
int main()
{
printf(7+"%c","sundaram");  
}

印刷“aram”。无法理解。

3 个答案:

答案 0 :(得分:6)

这是未定义的行为。

C中的字符串文字是指向预初始化内存块的指针 巧合的是,你的两个字符串文字占据了相邻的内存块 当您将7添加到指向第一个文字的指针时,您最终会指向下一个文字的中间位置。

您的程序数据按如下方式排列在内存中:

       %c\0sundaram\0
       |       |
"%c" --^       |
7 + "%c" ------^

因此,您最终使用两个指向同一个字符串printf并且没有格式说明符来调用("adam", "sundadam")

答案 1 :(得分:2)

行为未定义。只是碰巧数据在内存中布局如下:“%c \ 0sundaram \ 0”,你得到“sundaram”字符串的一部分作为格式字符串参数(在格式字符串中没有格式说明符的情况下) printf参数被忽略)。

答案 2 :(得分:2)

正如其他人所指出的那样,行为是 undefined ,因为表达式7+"%c"不指向数组中的元素或指向数组末尾的元素。有关详细信息,请参阅在线C语言标准,草案n1256,第6.5.6节¶8。

巧合的是,你的字符串就像这样(使用虚构的起始地址)在内存中布局:

Address         0x00  0x01  0x02  0x03
-------         ----------------------
0x00008000      '%'   'c'   0     's'
0x00008004      'u'   'n'   'd'   'a'
0x00008008      'r'   'a'   'm'   0

“%c”从0x00008000开始,“sundaram”从0x000080003开始。

致电时

printf(7+"%c", "sundaram");

数组表达式“%c”从类型char [3]转换为char *,其值是数组中第一个元素的地址,或0x00008000。因此,表达式7+"%c"的计算结果为7 + 0x00008000或0x00008007。从0x00008007开始的字符串是“aram”。

由于“aram”不包含转换说明符,因此会计算第二个参数(“sundaram”,其计算结果为0x00008003),但会被忽略(第7.19.6.1节,第2节)。

由于行为未定义,任何结果都是可能的;不能保证使用不同的编译器或不同的编译器设置发生此特定结果。