无法理解此 C 代码片段的输出

发布于 2024-10-10 13:35:08 字数 143 浏览 0 评论 0原文

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

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故事和酒 2024-10-17 13:35:08

这是未定义的行为。

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

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

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

因此,您最终会使用指向同一字符串 ("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:

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

Therefore, you end up calling printf with two pointers into the same string ("adam", "sundadam") and no format specifiers.

寂寞笑我太脆弱 2024-10-17 13:35:08

正如其他人指出的那样,该行为是未定义,因为表达式 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 节)。

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

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):

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

"%c" starts at 0x00008000 and "sundaram" starts at 0x000080003.

When you call

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

the array expression "%c" is converted from type char [3] to char *, and its value is the address of the first element in the array, or 0x00008000. The expression 7+"%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.

人│生佛魔见 2024-10-17 13:35:08

该行为是未定义的。碰巧数据在内存中的布局如下:“%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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文