【问题标题】:Using an unsigned int in a do-while loop在 do-while 循环中使用无符号整数
【发布时间】:2020-03-19 14:40:11
【问题描述】:

我是 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 工作?

感谢任何帮助!

【问题讨论】:

  • 无符号整数不能有负值。这就是使用无符号变量的重点:只有正数,但你会得到一个“更大范围”的值(即最大的数字是比更大的有符号整数大 2 的幂)
  • 可能有一些方法可以进行时髦的铸造以使其发挥作用,但这会令人困惑且毫无意义。你有理由不只使用int吗?
  • 我使用 unsigned int 的原因是因为我正在研究的一个问题需要我使用它
  • while(mins

标签: c algorithm loops int do-while


【解决方案1】:

有没有办法可以更改我的代码以使 unsigned int 工作?

可能的各种方法。

读为int,然后转换为unsigned


鉴于“您每天睡觉的小时数:”意味着大约 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;

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 那么在这种情况下,使用 unsigned int 而不是有符号的 int 是没有意义的,对吧?
    【解决方案3】:

    我会尝试下一个测试:

    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。一个正整数,其最高有效位为 0,ordinary binary manner 的其余坐标为 1 和 0。

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

    示例: 假设 N = 4,K = 7。使用 4 位的 7 的二进制表示: 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 称为正数。这就是您意想不到的“错误”的来源。

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

    【讨论】:

      猜你喜欢
      • 2021-07-18
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2012-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多