为什么这不是一个无限循环?

时间:2013-09-15 09:38:43

标签: c

为什么以下循环无限次运行?我希望在达到65535时,i应该溢出回零。

#include<stdio.h>
int main()
{
    short int i = 0;  //(assume short int is 2 bytes)
    for(i<=5 && i>=-1; ++i; i>0)
        printf("%u\n", i);
    return 0;
}

修改

这个怎么样?

#include<stdio.h>
int main()
{
    int x=1, y=1;
    for(; y; printf("%d %d\n", x, y))
    {
        y = x++ <= 5;
    }
    printf("\n");
    return 0;
}

运行正常并打印

2 1
3 1
4 1
5 1
6 1
7 0

是什么让它终止?

5 个答案:

答案 0 :(得分:7)

你在这里依赖签名溢出,它会调用 undefined behvaiour 。编译器完全有权将其优化为无限循环,或者不执行,或者执行完全不同的操作。

答案 1 :(得分:2)

有两个原因。

首先,正如Oli Charlesworth指出的那样,你正在调用未定义的行为。

然后,65535到0是无符号溢出,但你有一个短(签名)int ,所以你(可能!)有一个签名< / strong>从32767溢出到-32768。因此,您的if条件可能会失败。

您的打印i作为无符号将其转换为仅在printf内的无符号,从而阻止您意识到可能发生的情况。在我的系统上,没有优化,我得到了

...
32764
32765
32766
32767
4294934528 <-- this is -32768
4294934529 <-- this is -32767, we're going backwards...
4294934530
4294934531
...
4294967295 <-- and this is -1, and your condition fails, and the loop exits.

但无法保证所有编译器和平台都会出现这种情况!

答案 2 :(得分:0)

循环运行的次数取决于循环的决策制定部分,而在for循环中,这部分是放置++i的中间部分 当溢出发生时,你是正确的,++i的值返回0,而C中的0等于false。所以循环终止。

试试这个,你的循环将无限时间运行。

#include<stdio.h>
int main()
{
    short int i = 0;  //(assume short int is 2 bytes)
    for(i<=5 && i>=-1; ;++i  )
        printf("%u\n", i);
    return 0;   
}

答案 3 :(得分:0)

您是否依靠short int的限制来限制值而不是自己定义限制?这是非常糟糕的做法,因为编译器没有关于处理超出其界限的值的规则。一旦智能编译器溢出,它就会抛出一个错误。不要那样做。

为什么你想要一个无限循环?

答案 4 :(得分:0)

您的条件语句是 ++ i ,当它返回0时,您的循环终止。 i&gt; 0 什么都不做,你的for循环初始化器什么都不做。您的 for 循环等同于

for( ; (++i) != 0; )