私のコードは:
#include<stdio.h>
main() {
short int i=0;
for(i<=5 && i>=-1; ++i; i>0)
printf("%d, ",i);
return 0;
}
出力:-
どこから始まるのかわかりませんが、シーケンスで終わります
..., -4, -3, -2, -1
このコードスニペットの動作を理解するのを手伝ってもらえますか?
for(i<=5 && i>=-1; ++i; i>0)
と同等です:
for(; ++i;)
i<=5 && i>=-1
とi > 0
式には副作用がないためです。
これで、制御式はです。これは、が評価++i
されるまでループが実行されることを意味します。++i
0
i
はshort
オブジェクトなので、++i
と同等i = (int) i + 1
です。
がオブジェクトに(int) i + 1
変換され、値がで表現できない場合、変換は実装で定義されます(C99、6.3.1.3p3を参照)。short
i
short
実装では、値がで表現できない場合、値はshort
折り返され、巨大な負の値(SHRT_MIN
)になります。++i
ループは、制御式がになるまで繰り返し実行され0
ます。
構文的に正しい、不正な形式の文です。意味のある初期化(たとえば、i = 0)の代わりに、trueと評価されるステートメントがあります。比較として、変数iを増やすだけで、iがゼロに達したときに終了します。反復が成功するたびに実行されるendステートメントは、何もしません。
ステートメントの動作部分は、while(++ i)printf( "%d"、i);と同等です。および(2の補数のプロパティのため、1、2、3、4、...、32766、32767からループし、負の数-32768、-32767、...、-3、-2にラップします。 、-1.(i == 0の場合、次の反復で停止します)
編集:条件i == 0が満たされるまで、ループはおそらく永久に続きます。コンピューターでの整数計算は、通常、モジュロ2^16またはモジュロ2^32、モジュロ2 ^ 64などで計算されます。16ビット数で使用可能な65536の異なる値の範囲を2つの範囲にマップすると非常に便利です:0 ...32767および32768...65535。後者の部分は、正の整数[符号なし]または値が(x-65536)の負の整数として解釈できます。署名されたc言語キーワードは、コンピューターにそれを実行するように要求します。
の
for(i<=5 && i>=-1; ++i; i>0)
これ
i<=5 && i>=-1
本当を意味するので0 <= 5 and 0 >= -1
そして、なぜあなたは-2、-1を得るのですか?バッファオーバーフローです。MAX_INTに1を加算すると、負の数になります
01111
1を追加
10000
最初のビットは負のビットです(1-デジタルは負、0-は正)
これをチェックしてくださいhttp://en.wikipedia.org/wiki/Two%27s_complement
int
また、次のように変更してみることができますunsigned int
出力は
1, 2, 3, 4, 5,
....
-5, -4, -3, -2, -1
あなたはこれをチェックすることができます
program.exe > out.txt
ループ内の句がfor
混乱しているため、最大の短整数値までカウントアップしています。これに1を加えると、最小の短整数値である負の数にループし、0になるまでカウントアップを続けます。0になると、ループは最終的に停止します。ループする理由は、整数は通常2の補数で格納され、ほとんどのCPUとコンパイラはオーバーフローに対して特別なことを何もしないためです。結果が意味をなさない場合でも、追加し続けるだけです。2の補数では、最大整数値は0111...
;として表されます。これに1を加える1000...
と、最小の負の整数であるが得られます。
C forループでは、式はです。for(initializer; condition; update) body
イニシャライザは、変数を初期化するために、最初に1回実行されます。いくつかの比較を行っているだけなので、基本的にループでは何もしません。
条件は、反復を実行する前に、反復ごとに1回実行され、ループが継続するかどうかをテストします。あなたの状態は++i
です。これにより、増分i
(1が追加)され、結果が返されます。したがって、最初のパスでは、i
から開始し、それをに0
インクリメントします。ループはその値を使用して、ループを続行するかどうかを決定します。Cでは、それ以外の数値は「真」と見なされるため、ループが続行されます。antは、がであるポイントに到達するまで続行するため、インクリメントすると、が残ります。これは誤った値です。1
for
0
i
-1
0
更新式は、本体の後に反復ごとに1回実行され、反復を続行するために必要な変数を更新します。ここでは、値を使用しない比較を行っているだけなので、基本的には何もしていません。
結局、forループは基本的に次のようになります。
for (;++i;)
printf("%d, ",i);
これも同じです:
while (++i)
printf("%d, ",i);
おそらく代わりにあなたが意味したのは:
for (i = 0; i <= 5; ++i)
printf("%d, ",i);