为什么这个程序提供输出 'y'
#include <stdio.h>
int main(void) {
char ch='abcdefghijklmnopqrstuvwxy';
printf("%c",ch);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Moh*_*ain 10
这是一个多字符文字.
包含多个c-char的普通字符文字是多字符文字.多字符文字具有int类型和 implementation-de fi ned值.
同样来自C11规格中的6.4.4.4/10
整数字符常量的类型为int.包含映射到单字节执行字符的单个字符的整数字符常量的值是解释为整数的映射字符的表示的数值.包含多个字符(例如,'ab')的整数字符常量的值,或包含不映射到单字节执行字符的字符或转义序列的值是 实现定义的.如果整数字符常量包含单个字符或转义序列,则其值是当char类型的对象(单值字符或转义序列的值)转换为int类型时生成的值.
所以char ch = 'abcdefghijklmnopqrstuvwxy'你的系统上的行(假设4字节int)可能编译为:
char ch = 0x76777879; // SOME int value (may be different, but documented in the compiler documents)
Run Code Online (Sandbox Code Playgroud)
ch将被分配'abcdef...y' ,其可能等同 (int)0x616263646566...79于ascii编码并溢出整数.这就是为什么会gcc产生以下警告的原因:
multicharlit.c:在函数'main'中:
multicharlit.c:4:13:警告:字符常量对于其类型太长[默认情况下启用]
multicharlit.c:4:5:警告:隐式常量转换溢出[-Woverflow ]
它出现在您的系统上,最低有效8位用于分配ch.因为你的字符文字是常量,所以这很可能发生在编译时:(例如,当我编译时发生以下情况gcc)
$ cat multicharlit.c
#include <stdio.h>
int main(void) {
char ch='abcdefghijklmnopqrstuvwxy';
printf("%c",ch);
return 0;
}
$ gcc -O2 -fdump-tree-optimized multicharlit.c
$ cat multicharlit.c.143t.optimized
;; Function main (main) (executed once)
main ()
{
<bb 2>:
__builtin_putchar (121);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从放松的评论中窃取一些善意
请记住,单引号字符常量的类型是
int,但是您将其分配给achar,因此必须将其截断为单个字符.
'a'例如,类型是int在C.(不要与混淆'a'在C++其是炭.在另一方面型的'ab'是int在两个 C和C++.)
现在,当您将此int类型分配给某个char类型并且值大于可以用a表示时char,则需要进行一些挤压以使结果适合更宽的类型char,并且实际结果是实现定义的.