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

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

它的印刷品是“aram”。不明白怎么回事。

最佳答案

正如其他人所指出的,行为是未定义的,因为表达式7+"%c"不指向数组中的元素或数组结束后的元素。有关详细信息,请参阅联机C语言标准,草稿n1256,§6.5.6¨8。
巧合的是,字符串在内存中的布局与so类似(使用一个虚构的起始地址):

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+0x00008000或0x00008007。从0x00008007开始的字符串是“aram”。
由于“aram”不包含转换说明符,因此计算第二个参数(“sundaram”,其计算结果为0x00008003),但在其他情况下忽略(§7.19.6.1,§2)。
由于行为是未定义的,因此任何结果都是可能的;此特定结果不能保证在不同的编译器或不同的编译器设置下发生。

08-17 23:32