在char

时间:2015-07-10 07:59:27

标签: c char

为什么此程序提供输出'y'

#include <stdio.h>

int main(void) {
    char ch='abcdefghijklmnopqrstuvwxy';
    printf("%c",ch);
    return 0;
}

Code at ideone

2 个答案:

答案 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;

}

还从unwind's comment

中窃取了一些善意
  

请记住,单引号字符常量的类型为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变量用于保存一个字符。