在 do-while 循环中使用 unsigned int

Using an unsigned int in a do-while loop

我是 c 语言编码的新手,我一直在努力研究无符号整数。这是我的代码:

    #include <stdio.h>

     int main(void)
     {
        unsigned int hours;

        do
        {
          printf("Number of hours you spend sleeping a day: ");
          scanf(" %u", &hours);
        }
        while(hours < 0);

        printf("\nYour number is %u", hours);
     }

但是,当我 运行 代码并使用 (-1) 时,它不会像应该的那样再次询问问题,而是打印出来(您的号码是 4294967295)。如果我将 unsigned int 更改为普通 int,代码工作正常。有没有办法可以更改我的代码以使 unsigned int 工作?

感谢任何帮助!

unsigned int 不能包含负数。它很有用,因为它可以存储一个完整的 32 位数字(是常规 int 的两倍),但它不能存储负数所以当你尝试 read 你的负数 unsigned int 时,它被读作正数。尽管 int 和 unsigned int 都是 32 位数字,但它们的解释会有很大不同。

Is there a way I can change my code to make the unsigned int work?

可能有多种方法。

读取为int,然后转换为unsigned


给定 "Number of hours you spend sleeping a day: " 表示约 0 到 24 的小合法范围,读作 int 并转换。

int input;
do {
  puts("Number of hours you spend sleeping a day:");
  if (scanf("%d", &input) != 1) {
    Handle_non_text_input(); // TBD code for non-numeric input like "abc"
  } 
} while (input < 0 || input > 24);
unsigned hours = input;

我会尝试下一个测试:

do:{
    printf("enter valid input...")
    scanf("new input...")
} while (hours > 24)

为什么它会起作用? C 中的 unsigned int 是一个二进制数,32 位。这意味着它的最大值是 2^32 - 1。 注意:

2^32 - 1 == 4294967295。这不是巧合。负整数通常使用“Two's complement”方法表示。 关于该方法的一句话:

当我使用常规 int 时,它的最高有效位保留给符号:如果为负则为 1,如果为正则为 0。一个正 int 在它的最高有效位中保存 0,在 ordinary binary manner.

中的剩余坐标上保存 1 和 0

负整数,以不同的方式表示: 假设 K 是一个正数,用 N 位表示。 数(-K)在最高位用1表示,POSITIVE NUMBER:(2^(N-1) - K)占用N-1个最低位.

示例: 假设 N = 4,K = 7。7 使用 4 位的二进制表示: 7 = 0111(最高有效位保留给符号,记得吗?)

-7 ,另一方面:

-7 = concat(1, 2^(4-1) - 7) == 1001

另一个例子:

1 = 0001,-1 = 1111。

请注意,如果我们使用 32 位,-1 就是 1...1(总共有 32 个 1)。这正是 unsigned int 4294967295 的二进制表示。当您使用 unsigned int 时,您指示编译器将 -1 称为正数。这就是你意想不到的 "error" 的来源。

现在 - 如果您使用 while(hours>24),则可以排除大部分非法输入。我不确定你是否排除了所有非法输入。可能会想到一个负数,以便编译器在要求忽略符号时将其解释为 [0:24] 范围内的非负数,并将最高有效位称为 'just another bit' .