【问题标题】:Explanation for the given code output in CC中给定代码输出的解释
【发布时间】:2021-10-06 19:44:50
【问题描述】:

我用 C 写过代码

#include<stdio.h>

int main()
{
    char a = 128;
    char b = -128;
    printf("%c",a);
    printf("%c",b);
}

上面代码的输出是ÇÇ
使用 128 或 -128 输出结果是相同的。为什么?请尽可能使用二进制解释。

【问题讨论】:

  • {-128, 128} 之一超出了 8 位 2's complement char 的范围。如果char 被签名,范围是-128127...如果是unsigned,范围是0255。为了安全起见,请始终将您的字符保持在0127 之间。如果需要这些范围,请显式使用 signed charunsigned char

标签: c character-encoding char output


【解决方案1】:

有符号的char 类型的范围通常为 -128 到 127。由于 128 超出此范围,您的编译器会将其转换为具有相同 8 位位模式的值,即 -128。

【讨论】:

  • Confirm not UB in C ...见C11 6.3.1.3p3 ...它的实现定义
  • 如果charunsigned?不合格的char 是有符号还是无符号取决于实现(通常可以由编译器选项定义)。在这种情况下,-128 无效并被强制为 128。
  • @Clifford 签名的可能性更大,但答案不会改变任何一种方式 - 只要它是二进制补码 128 和 -128 在低 8 位中将具有相同的位模式。跨度>
  • @MarkRansom 结果没有改变,但您的回答非常具体地涉及签名。我同意有点迂腐,但如果要包含无符号,答案必须改变,因为虽然结果相同,但你关于为什么不适用的论点。
  • @Clifford 我还没有看到一个不默认为 signed char 的编译器,除非你特意用编译器选项指定它。所以我写了我认为有 99.9% 可能适用的答案。我本来打算邀请你自己写的,但我看到你已经写了。
【解决方案2】:

文字 -128 的类型为 int,在 32 位 2 的补码表示上具有位模式:

1111 1111 1111 1111 1111 1111 1000 0000

在这种情况下,当您将其分配给 char 时,会进行隐式转换(强制转换),因此仅使用 LSB 1000 000 或十进制的 128。因此结果是相同的。

严格来说,如果charsigned,则行为是实现定义的,并且标准以有点神秘的“as-if”术语为unsigned char 定义行为。 char 本身是有符号的还是无符号的,其实现本身就是定义为实际宽度以及 char 的范围。在实践中,尽管上述解释是这种情况下发生的情况,并且是任何使用 8 位 char 的实现最可能出现的行为,但 char 是有符号还是无符号都没有区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    相关资源
    最近更新 更多