【问题标题】:Why is the unsigned variable storing negative value? [duplicate]为什么无符号变量存储负值? [复制]
【发布时间】:2019-11-06 03:59:30
【问题描述】:

我已将 -1 分配给 unsigned int 并假设它会产生错误我编译了代码,令我惊讶的是它没有。我无法理解背后的原因。

我尝试打印值以手动检查它们,但它总是显示 -1。


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(int argc, char *argv[]) {
    unsigned int x = -1;
    printf("%u\n", x);
    int y = -1;
    printf("%d\n", y);
    if (x == y) {
        printf("\nsame");
    } else {
        printf("n s");
    }
    return 0;
}

预期的结果是错误或警告 但它按原样编译。

【问题讨论】:

  • 也许看看这个问题Your Answer
  • 是时候了解two's complement(这是在二进制计算机上表示负整数值的最常用方法)。
  • 如果您使用 gcc,请尝试使用选项 -wall 进行编译(所有警告)。
  • @SirJoBlack - 所有 C 标准都指定了该行为。从历史上看,它在 C 中是这样指定的,因为所有现实世界的实现都是这样。情况仍然如此。它是有符号整数上溢或下溢,会产生未定义的行为,并且硬件的处理方式有所不同。

标签: c unsigned-integer


【解决方案1】:

之所以有效,是因为:

unsigned int x = -1;

导致int-typed 文字-1 转换为unsigned int,这是一种标准的、明确指定的转换。 C11 规范草案说:

6.3.1.3 有符号和无符号整数

1 当一个整数类型的值被转换为另一个整数类型时 _Bool,如果值可以用新类型表示,则不变。

2 否则,如果新类型是无符号的,则重复转换该值 添加或 减去可以用新的最大值表示的最大值 直到值在新类型的范围内。60)

后者是这里发生的事情,所以假设 32 位整数 232 被添加,结果为0xffffffff

我不相信printf()%u 打印-1,这将是一个相当大的错误。

【讨论】:

  • 哦,是的,我只是在玩弄格式说明符以了解正在发生的事情,我想在从我的 IDE 发布代码之前我可能已经把它留在了那里。
【解决方案2】:

这是标准允许的。当您将-1 分配给unsigned 类型时,至少从概念上讲,该值将转换为可以通过重复添加 2n 来表示的数字,其中n 是该类型的位数。

这种转换也发生在比较 x == y 中的 signed 类型(该比较发生在 unsigned 算术中,因为其中一个变量是 unsigned 类型)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 2021-11-13
    • 2012-11-16
    相关资源
    最近更新 更多