在以下代码中,行为是否未定义?
#include<stdio.h>
int main()
{
printf(7+"%c","sundaram");
}
印刷“aram”。无法理解。
答案 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节)。
由于行为未定义,任何结果都是可能的;不能保证使用不同的编译器或不同的编译器设置发生此特定结果。