-2

次のループが無限回実行されないのはなぜですか? 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

終了する理由は何ですか?

4

5 に答える 5

7

ここでは、未定義の動作を呼び出す符号付きオーバーフローに依存しています。コンパイラは、これを無限ループに最適化するかどうか、またはまったく異なることを行う権利を十分に持っています。

于 2013-09-15T09:40:10.723 に答える
2

2つの理由。

まず、Oli Charlesworth が指摘したように、未定義の動作を呼び出しています。

次に、65535 から 0 は符号なしオーバーフローですが、短い (符号付き) intがあるため、32767 から -32768 への符号付きオーバーフローが発生する可能性があります。したがって、あなたのif状態は失敗する可能性があります。

unsigned として印刷iすると、 内でのみ unsigned に変換され、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.

しかし、これがすべてのコンパイラとプラットフォームで常に起こるという保証はありません!

于 2013-09-15T09:47:17.563 に答える
0

条件ステートメントは++iです。これが 0 を返すと、ループが終了します。i > 0は何もせず、for ループ初期化子は何もしません。forループは次と同等です

for( ; (++i) != 0; )
于 2013-09-15T10:07:05.567 に答える
0

ループの実行回数は、ループの意思決定部分に依存し、 for ループでは、この部分は中央の部分であり++i 、オーバーフローが発生したときに正しい値が++i0 を返し、 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;   
}
于 2013-09-15T09:47:44.143 に答える
0

自分で制限を定義するのではなく、値を制限するために short int の制限に依存していますか? コンパイラには、境界外の値の処理に関する規則がないため、これは非常に悪い方法です。スマート コンパイラは、オーバーフローすると単純にエラーをスローします。そうしないでください。

とにかく、なぜ無限ループが必要なのですか?

于 2013-09-15T09:48:40.250 に答える