#include <stdio.h>
int main()
{
printf("%c\n", 'abcd');
printf("%p\n", 'abcd');
printf("%c\n", 0x61626364);
printf("%c\n", 0x61626363);
printf("%c\n", 0x61626365);
return 0;
}
我想问这一行:printf(&#34;%c \ n&#34;,&#39; abcd&#39;);
在这一行中,结果是&#39; d&#39;但是,我无法理解为什么&#39; d&#39;出来了。
我试着寻找其他的回忆。在这种情况下,我发现其他记忆都包含所有字母
请解释一下为什么结果是&#39; d&#39;以及为什么其他记忆都包含所有字母
谢谢。
答案 0 :(得分:4)
'abcd'
是一个多字符常量,其值是实现定义的。
C11§6.4.4.4字符常量第10节
整数字符常量的类型为
int
。整数字符常量的值 包含映射到单字节执行字符的单个字符是 解释为整数的映射字符表示的数值。 包含多个字符的整数字符常量的值(例如,'ab'
),或包含未映射到单字节的字符或转义序列 执行字符,是实现定义的。如果包含整数字符常量 单个字符或转义序列,其值是当对象具有时产生的值 类型char
,其值是单个字符或转义序列的值转换为 输入int
。
一个常见的实现为'abcd'
提供'a' * 256 * 256 * 256 + 'b' * 256 * 256 + 'c' * 256 + 'd'
(1633837924
)的值,您可以使用"%d"
打印它在实现中的值。虽然是合法的C,但它在实践中很少使用。
答案 1 :(得分:1)
您的代码错误。使用最新的GCC编译器编译时,使用
启用警告gcc -Wall -Wextra u.c
你得到了
u.c: In function 'main':
u.c:5:20: warning: multi-character character constant [-Wmultichar]
printf("%c\n", 'abcd');
^
u.c:6:20: warning: multi-character character constant [-Wmultichar]
printf("%p\n", 'abcd');
^
u.c:6:5: warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int' [-Wformat=]
printf("%p\n", 'abcd');
^
从技术上讲,您处于糟糕的undefined behavior案例(以及 unspecified behavior 的多字符常量)和{{3}符合标准的实现可能会发生。
我从未见过像'abcd'
这样的多字符常量的任何有用情况。我相信它们毫无用处,而且大部分都是历史人工制品。
要解释实际发生的事情,它是特定于实现的(取决于编译器,处理器,优化标志,ABI,运行时环境......),你需要深入了解血腥细节(首先看看生成的汇编程序代码gcc -fverbose-asm -S
)以及anything特定printf
实现。
根据经验,你应该改进你的代码,以摆脱编译器能够给你的每一个警告(你的编译器有助于警告你)。它们是一些微妙的例外(但是你应该对它们的代码进行评论)。
答案 2 :(得分:1)
printf("%c\n", 'abcd');
如前所述,'abcd'
的值是实现定义的。在您的实施中,其值为0x61626364
,因此其行为与您的第三次printf
调用相同。见下文。
printf("%p\n", 'abcd');
如前所述,%p
用于打印指针。 <{1}}不是指针,因此此调用无效。
'abcd'
printf("%c\n", 0x61626364);
printf("%c\n", 0x61626363);
printf("%c\n", 0x61626365);
的规范如下:
如果不存在
%c
长度修饰符,则l
参数将转换为int
,并写入生成的字符。
unsigned char
到int
的转化定义明确,并将值{im} unsigned char
减少。在大多数实现中,这意味着它需要该数字的最低8位。
UCHAR_MAX+1
,0x61626364
和0x61626363
的最低8位为0x61626365
,0x64
和0x63
,其中ASCII对应{ {1}},0x65
和'd'
,因此ASCII实现将打印这些字符。
答案 3 :(得分:0)
您的代码
printf("%c\n", 'abcd');
导致输出
d
由于&#34;%c&#34;指定单个字符。因为提供了多个字符而不是单个字符,所以多字符常量被转换为&#39;取一个字符,取字符串的最后一个字符。
提供预期单个字符的字符串的结果是&#34;实现定义的&#34;行为。这意味着不同的编译器可以不同地处理它。见stackoverflow.com/multiple-characters-in-a-character-constant。