无法理解此 C 代码片段的输出
在下面的代码中,行为是否未定义?
#include<stdio.h>
int main()
{
printf(7+"%c","sundaram");
}
其印刷“aram”。不明白怎么办。
In the following code, is the behaviour undefined ?
#include<stdio.h>
int main()
{
printf(7+"%c","sundaram");
}
Its printing "aram". Can't understand how.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是未定义的行为。
C 中的字符串文字是指向预初始化内存块的指针。
巧合的是,您的两个字符串文字占用了相邻的内存块。
当您将
7
添加到指向第一个文字的指针时,您最终会指向下一个文字的中间。您的程序的数据在内存中的排列如下:
因此,您最终会使用指向同一字符串
("adam", "sundadam")
的两个指针来调用printf
,并且没有任何格式说明符。This is undefined behavior.
A string literal in C is a pointer to a a block of pre-initialized memory.
By coincidence, your two string literals occupy adjacent blocks of memory.
When you add
7
to the pointer to the first literal, you end up pointing into the middle of the next literal.Your program's data is arranged in memory like this:
Therefore, you end up calling
printf
with two pointers into the same string("adam", "sundadam")
and no format specifiers.正如其他人指出的那样,该行为是未定义,因为表达式
7+"%c"
不指向数组内的元素或超出数组末尾的元素。请参阅在线 C 语言标准草案 n1256 , § 6.5.6 ¶ 8 了解详细信息。巧合的是,你的字符串在内存中的布局如下(使用虚构的起始地址):
“%c”从 0x00008000 开始,“sundaram”从 0x000080003 开始。
当调用
数组表达式时“%c”从类型
char[3]
转换为char *
,其值是数组中第一个元素的地址,或 0x00008000。因此,表达式7+"%c"
的计算结果为 7+0x00008000 或 0x00008007。从 0x00008007 开始的字符串是“aram”。由于“aram”不包含转换说明符,因此会计算第二个参数(“sundaram”,其计算结果为 0x00008003),但会被忽略(第 7.19.6.1 节,第 2 节)。
由于行为未定义,任何结果都是可能的;不保证使用不同的编译器或不同的编译器设置会发生此特定结果。
As others have pointed out, the behavior is undefined because the expression
7+"%c"
does not point to an element within the array or one past the end of the array. See the online C language standard, draft n1256, § 6.5.6 ¶ 8 for details.By coincidence your strings are laid out in memory like so (using an imaginary starting address):
"%c" starts at 0x00008000 and "sundaram" starts at 0x000080003.
When you call
the array expression "%c" is converted from type
char [3]
tochar *
, and its value is the address of the first element in the array, or 0x00008000. The expression7+"%c"
thus evaluates to 7+0x00008000, or 0x00008007. The string that starts at 0x00008007 is "aram".Since "aram" contains no conversion specifiers, the second argument ("sundaram", which evaluates to 0x00008003) is evaluated but otherwise ignored (§ 7.19.6.1, ¶ 2).
Since the behavior is undefined, any result is possible; this particular result isn't guaranteed to happen with a different compiler, or with different compiler settings.
该行为是未定义的。碰巧数据在内存中的布局如下:“%c\0sundaram\0”,并且您将“sundaram”字符串的一部分作为格式字符串参数(在剩余格式字符串中缺少格式说明符的情况下) printf 参数被忽略)。
The behaviour is undefined. It just so happens that the data is laid out in memory like this: "%c\0sundaram\0", and you get the part of "sundaram" string as a format string argument (in absence of format specifiers in a format string remaining printf arguments are ignored).