为什么此程序提供输出'y'
#include <stdio.h>
int main(void) {
char ch='abcdefghijklmnopqrstuvwxy';
printf("%c",ch);
return 0;
}
答案 0 :(得分:10)
这是一个多字符文字。
包含多个c-char的普通字符文字是a 多字形文字。多字符文字的类型为int和 实施定义值。
同样来自C11规范中的6.4.4.4/10
整数字符常量的类型为int。整数的值 包含映射到a的单个字符的字符常量 单字节执行字符是数值 解释为整数的映射字符的表示形式。该 包含多个的整数字符常量的值 字符(例如,'ab'),或包含字符或转义序列 没有映射到单字节执行字符,是 的实现定义即可。如果整数字符常量包含a 单个字符或转义序列,其值是产生的值 当一个char类型的对象,其值是单个的 字符或转义序列转换为int。
因此系统上的行char ch = 'abcdefghijklmnopqrstuvwxy'
(假设4字节为int)可能编译为:
char ch = 0x76777879; // SOME int value (may be different, but documented in the compiler documents)
ch
将在ascii编码中分配'abcdef...y'
which may be equivalent to (int)0x616263646566...79
并溢出整数。这就是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;
}
中窃取了一些善意
请记住,单引号字符常量的类型为
int
, 但是你要将它分配给char
,所以必须将它截断为a 单个字符。
'a'
的类型例如int
中的C
。 (不要与'a'
C++
中的'ab'
混淆。另一方面,int
的类型为{{1>} {{ 1}}和C
。)
现在,当您将此C++
类型分配给int
类型并且值大于char
时,可能需要进行一些挤压以适应结果更宽的类型char
,实际结果是实现定义。
答案 1 :(得分:0)
如果您打算打印 abcdefghijklmnopqrstuvwxy ,那么您应该将其存储到字符串变量而不是char变量中(char ch [50] = char abcdefghijklmnopqrstuvwxy;)。
字符串变量可以包含多个字符,其中char变量用于保存一个字符。