【问题标题】:assigning more than one character in char在 char 中分配多个字符
【发布时间】:2021-09-15 20:01:12
【问题描述】:

为什么这个程序会输出'y'

#include <stdio.h>

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

Code at ideone

【问题讨论】:

标签: c char


【解决方案1】:

这是一个多字符文字。

包含多个 c-char 的普通字符文字是 多字符文字。多字符文字的类型为 int 和 实现定义的值

同样来自 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)

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' 的类型例如是 int in C。 (不要与 C++ 中的 'a' 混淆,后者是一个字符。另一方面,'ab' 的类型是 both CC++ 中的 int。)

现在,当您将此int 类型分配给char 类型并且值大于char 可以表示的值时,需要进行一些挤压以使结果适合更宽的类型@987654346 @ 并且实际结果是实现定义的。

【讨论】:

  • @LoveToCode:编译器必须记录实现定义的行为,并且可能您正在使用的编译器将多字符常量中的最后一个字符放入字符值中。它可能是实现选择的第一个、第四个或任何其他字符——它只需要记录它选择做什么(然后它也应该这样做)。
【解决方案2】:

如果您打算打印 abcdefghijklmnopqrstuvwxy,那么您应该将其存储到字符串变量而不是 char 变量中(char ch[50] = char abcdefghijklmnopqrstuvwxy;)。

字符串变量可以容纳多个字符,其中char变量用于容纳一个字符。

【讨论】:

    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2021-04-15
    相关资源
    最近更新 更多