【问题标题】:Why the value of signed char is greater than the unsigned int [duplicate]为什么有符号字符的值大于无符号整数[重复]
【发布时间】:2021-05-30 21:21:35
【问题描述】:
#include <stdio.h>

int main() {

    unsigned int i = 23;
    signed char c = -23;
    if (i<c)
       puts("TRUE");

    return 0;
}

为什么以下程序的输出是 TRUE,即使我使用了可以存储从 -128 到 127 的有符号字符。

【问题讨论】:

标签: c


【解决方案1】:

您的i &lt; c 比较具有两种不同类型的操作数,因此具有较小类型(较低等级)的操作数将转换为另一个类型。在这种情况下,由于-23 不能表示为unsigned int,并且按照“通常的算术转换”,它将最终得到一个大大大于+23(实际上是UINT_MAX + 1 - 23)的值,根据段落#2 以下摘自this (Draft) C11 Standard

6.3.1.3 有符号和无符号整数

1    当一个整数类型的值转换为 _Bool 以外的其他整数类型时,如果该值可以用新的类型表示,则保持不变。
2    否则,如果新类型是无符号的,则值转换为 反复加或减一大于最大值 可以用新类型表示,直到值在 新类型。
3    否则,新类型被签名并且 价值不能在其中体现;结果要么是 实现定义或实现定义的信号是

您可以通过将c 分配给单独的unsigned int 并打印其值来查看此转换,如以下代码所示。假设是 32 位 unsigned int,您可能会看到 4294967273 的值(实际上,它大于 23)。

#include <stdio.h>

int main()
{
    unsigned int i = 23;
    signed char c = -23;
    unsigned int uc = c; // Add a diagnostic line ...
    printf("%u\n", uc);  // ... and show the value being used in the comparison
    if (i < c) {
        printf("TRUE");
    }
    return 0;
}

注意:这两个变量(ic)的相对 大小 有点像红鲱鱼;即使您将c 声明为signed int c = -23;,由于Usual Arithmetic Conversions(链接由Jonathan Leffler 的评论提供),您仍然会得到相同的结果——请注意signed int 不能代表所有可能 unsigned int 的 em> 值,因此最后一个“空心”子弹将发挥作用。

【讨论】:

    【解决方案2】:

    为了进行比较,必须将最小变量(char,8 位)提升为较大变量(整数,32 位)的大小和符号。但是这样一来,-23 就变成了 4294967273。这比 23 大得多。

    如果您将c 与一个有符号 整数进行比较,则符号提升不会导致任何变化,并且测试会按预期运行。

    【讨论】:

      猜你喜欢
      • 2012-11-16
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多