【问题标题】:Why the infinite loop when data type is unsigned int?为什么当数据类型为 unsigned int 时会出现无限循环?
【发布时间】:2015-05-23 16:25:44
【问题描述】:

下面的代码运行完美。给出正确的输出,但是,当我将变量的符号从有符号更改为无符号时,程序运行到无限循环。 程序是求整数的阶乘。 任何变量的值都不会在任何地方变为负数 我知道 unsigned int 的模块化行为。

#include<stdio.h>

int main(void)
{
    int a[200], i,index, number, next, count, temp, test, x;

    scanf(" %d", &test);

    while(test--)
    {
        scanf(" %d", &number);
        a[0]=1;
        count=1;    //1 digit
        for(next=2;next<=number;++next)
        {
            index=0;temp=0;
            for(i=0;i<count;++i)
            {
                x=a[index]*next+temp;
                a[index]=x%10;
                temp=x/10;
                ++index;
            }
            while(temp!=0)
            {
                a[count++]=temp%10;
                temp=temp/10;
            }
        }
        for(i=count-1;i>=0;--i)
        printf("%d",a[i]);
        printf("\n");
    }
    return 0;
}

【问题讨论】:

    标签: c


    【解决方案1】:

    问题是,

    for(i=count-1;i>=0;--i)
    

    如果i 未签名,则永远不会退出。因为i 是无符号的,所以它总是大于或等于零,因此循环无法结束。

    【讨论】:

      【解决方案2】:

      unsigned int 永远不会是负数,所以i &gt;= 0 一直持有true,这意味着像这样的循环

      unsigned int value;
      
      value = 10;
      while (value-- >= 0) {}
      

      实际上是一个无限循环,你的for (i = count - 1 ; i &gt;= 0 ; --i) 也是。

      编译器会对此发出警告,因此如果您编译代码时将正确的标志传递给编译器,它应该会告诉您条件始终为真。

      您应该注意,虽然&gt;= 在这方面没有任何区别,

      unsigned int value;
      
      value = 10;
      while (value-- != 0) {}
      

      确实有效,就像while (value-- &gt; 0) 一样,因为value 可以是0,但不能是&lt; 0

      还有,没有unsigned int 整数溢出,所以循环将是无限的而不会导致未定义的行为,this answer 解释了当你将1 添加到最大值时会发生什么,如果你减去一个最小值,那么我相信您可以“猜测”同一个答案会发生什么。

      【讨论】:

      • 我想你的意思是说i &gt;= 0 成立。
      • (i = 0) &gt; 0 == false 问题出在i &gt;= 0 的for循环测试中。
      • @Jens 对,在某些时候可能是 0,所以 i &gt; 0 并不总是正确的。
      • 这很好解释。谢谢。
      • @AshutoshNarang 您可以接受您认为对您更有效的答案,似乎您接受的答案是有效的,但请记住,寻求解决方案的程序员访问了该站点,并且他们经常使用以前问题的答案。
      【解决方案3】:

      正如其他答案已经指出的那样,循环

      for(i=count-1;i>=0;--i)
      
      如果i 是无符号的,

      是一个无限循环。它可以改写成不同的形式

      for (i = count - 1; i != -1; --i)
      

      这对签名和未签名的i 都适用。但是,有些人可能会发现它的可读性不如原版。

      【讨论】:

        猜你喜欢
        • 2019-05-11
        • 2017-01-31
        • 2018-11-06
        • 2016-08-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-31
        • 2010-10-23
        • 2021-10-28
        相关资源
        最近更新 更多