【问题标题】:How compiler behaves on out of range char value?编译器如何处理超出范围的字符值?
【发布时间】:2018-08-21 16:21:18
【问题描述】:
char ch = 1107;
printf("ch = %c", ch);

上面的代码打印 S.

我不明白这是怎么发生的。我给出了一个超出范围的 char 类型值。编译器如何得到这个值“S”(ASCII 83)?

【问题讨论】:

    标签: c char type-conversion


    【解决方案1】:

    运行这个演示程序

    #include <stdio.h>
    
    int main(void)
    {
        printf( "%#x\n", 1107 );
        printf( "%c\n", 0x53 );
    
        return 0;
    }
    

    它的输出是

    0x453
    S
    

    所以编译器只提取整数常量的最低字节并将存储的值分配给 char 类型的对象,

    【讨论】:

    • 我不明白你的演示。尤其不是 53。
    • 不会是 printf("%d\n", (char) 1107); 一个更好的例子来展示这种行为吗?
    • @PaulOgilvie 这个值 453 是常量 1107 的十六进制表示。因此最低字节包含 53 并分配给对象 ch。写成 char ch = ( char )1107; 会更直接;
    • 所以53 应该是0x53
    • 这个例子还不清楚。我建议第二行应该是printf( "%c\n", 0x1153 );,因为现在高字节(0x11)将被“切掉”,只有低字节(0x53)会被打印出来,那就是字母S。
    【解决方案2】:

    如果 1107 太大而无法放入 char(通常是,但 char 可能大于 8 位),并且 charunsigned,则 1107 将转换为 char具有正常的环绕行为。如果charsigned,则转换是实现定义的,并且可能会引发实现定义的信号。

    在此ch 扩展为int 之后,因为它在变量参数列表中传递。

    在内部,在 printf 内部,int 被转换为 unsigned char,应用正常的环绕规则。

    【讨论】:

    • 你为什么要减去?你在取模吗?
    • @Lyrk:我把那部分删了,因为问题的症结在于ch 的类型:所有有影响力的缩小转换都发生在那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 2023-01-08
    • 2023-03-25
    • 2012-06-23
    • 1970-01-01
    相关资源
    最近更新 更多