Can';我无法理解这个C代码段的输出

Can';我无法理解这个C代码段的输出,c,printf,C,Printf,在以下代码中,行为是否未定义 #include<stdio.h> int main() { printf(7+"%c","sundaram"); } #包括 int main() { printf(7+%c”,“sundaram”); } 它的印刷品是“阿拉姆”。无法理解。这是未定义的行为 C中的字符串文字是指向预初始化内存块的指针。 巧合的是,您的两个字符串文字占用了相邻的内存块。 将7添加到指向第一个文本的指针时,最终指向下一个文本的中间 程序数据在内存中的排列方式如下:

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

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

它的印刷品是“阿拉姆”。无法理解。这是未定义的行为

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

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

%c\0sundaram\0 | | "%c" --^ | 7 + "%c" ------^ %c\0sundaram\0 | | “%c”-^| 7+%c”------^
因此,您最终调用了
printf
,其中两个指针指向同一个字符串
(“adam”、“sundam”)
,并且没有格式说明符。

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

正如其他人所指出的,该行为是未定义的,因为表达式
7+%c”
未指向数组中的元素或数组末尾的元素。有关详细信息,请参见在线C语言标准草案§6.5.6¨8

巧合的是,字符串在内存中的布局是这样的(使用一个假想的起始地址):

“%c”从0x00008000开始,“sundaram”从0x00008003开始

当你打电话的时候

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

由于“aram”不包含转换说明符,因此对第二个参数(“sundaram”,其计算结果为0x00008003)进行了计算,但在其他方面被忽略(§7.19.6.1,^2)


由于行为未定义,因此任何结果都是可能的;这种特殊的结果不能保证在不同的编译器或不同的编译器设置下发生

谢谢。你说“在没有格式说明符的情况下……”但是有一个格式说明符。否?就printf而言,没有格式说明符-在您的情况下,未定义行为的影响是将“aram”作为格式字符串传递给printf,而printf没有格式说明符。谢谢。但是,为什么不考虑将“%c”作为格式说明符呢?如果我们将7替换为0,它将发出警告,输出将不显示任何内容,而它本应显示“%c”,因为当它查看内存中的顺序字符时,从“%c”所在的7开始,它将永远看不到“%c”。@Duad:您正在向它传递一个指向
“adam”
,而不是指向
“%c”
printf(7+"%c", "sundaram");