请解释这个结果。 printf(“%c”,“abcd”)

#include  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(“%c \ n”,’abcd’);
在这一行中,结果是“d”但是,我无法理解为什么’d’会出现。
我试着看看其他的回忆。 在这种情况下,我发现其他记忆都包含所有字母。
请解释一下为什么结果是’d’以及为什么其他记忆都有所有字母。
谢谢。

你的代码错了 。 当您使用最近的GCC编译器编译它时,启用警告

 gcc -Wall -Wextra uc 

你得到

  uc: In function 'main': uc:5:20: warning: multi-character character constant [-Wmultichar] printf("%c\n", 'abcd'); ^ uc:6:20: warning: multi-character character constant [-Wmultichar] printf("%p\n", 'abcd'); ^ uc:6:5: warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int' [-Wformat=] printf("%p\n", 'abcd'); ^ 

从技术上讲,您处于可怕的未定义行为情况 (以及多字符常量的未指定行为 ),并且任何事情都可能发生在符合标准的实现中。

我从来没有看到像'abcd'这样的多字符常量的任何有用情况。 我相信它们毫无用处,而且大部分都是历史人工制品。

要解释实际发生的事情,它是特定于实现的(取决于编译器,处理器,优化标志,ABI,运行时环境……),您需要深入了解血腥细节(首先看一下生成的汇编程序)代码与gcc -fverbose-asm -S )和你的libc特定的printf实现。

根据经验,你应该改进你的代码,以摆脱编译器能够给你的每一个警告(你的编译器有助于警告你)。 它们是一些微妙的例外(但是你应该对它们的代码进行评论)。

'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,但在实践中很少使用。

 printf("%c\n", 'abcd'); 

如前所述, 'abcd'的值是实现定义的。 在您的实现上,它的值是0x61626364 ,因此它的行为与您的第三个printf调用相同。 见下文。

 printf("%p\n", 'abcd'); 

如前所述, %p用于打印指针。 'abcd'不是指针,因此该调用无效。

 printf("%c\n", 0x61626364); printf("%c\n", 0x61626363); printf("%c\n", 0x61626365); 

%c的规范如下:

如果不存在l length修饰符,则将int参数转换为unsigned char ,并写入生成的字符。

int转换为unsigned char是明确定义的,并将模值减少为UCHAR_MAX+1 。 在大多数实现中,这意味着它需要该数字的最低8位。

0x616263630x61626365的最低8位是0x616263640x65 ,它们在ASCII中对应于'd''c''e' ,因此ASCII实现将打印这些字符。

你的代码

 printf("%c\n", 'abcd'); 

结果输出

 d 

由于“%c”指定了单个字符。 因为提供了多个字符而不是单个字符,所以通过获取字符串的最后一个字符将多字符常量“转换”为单个字符。

提供期望单个字符的字符串的结果是“实现定义的”行为。 这意味着不同的编译器可以不同地处理它。 请参阅stackoverflow.com/multiple-characters-in-a-character-constant 。