5

よくわからない割り当てのコードがあります。私は答えを知っていると確信していますが、何か忘れた場合に備えてコミュニティに再確認したいだけです. タイトルは基本的に安全なコーディングで、質問は結果を説明するだけです。

int main() {
   unsigned int i = 1;
   unsigned int c = 1;
   while (i > 0) {
     i = i*2;
     c++;
   }
   printf("%d\n", c);
   return 0;
}

私の推論は次のとおりです。

一見すると、コードが正の値に初期化され、増加し続けることを考えると、コードが永遠に実行されることが想像できます。最終的に値が大きくなりすぎて整数オーバーフローが発生するため、これはもちろん間違っています。これも完全に正しいわけではありません。最終的には変数 'i' が最後のビットを 1 にすることで強制的に署名され、負の数と見なされてループが終了するからです。したがって、割り当てられていないメモリへの書き込みではなく、整数オーバーフローが発生するのではなく、データ型に違反してループが終了します。

これが理由だと確信していますが、再確認したいだけです。ご意見はありますか?

4

7 に答える 7

5

いいえ、unsigned int符号付きの数値としてゼロと比較されることはありません。ループが終了する唯一のチャンスは、変数が正確にゼロになることです。

後者は、各反復で 2 (偶数) を乗算するため、確実に 1 回発生します。これにより、ゼロ ビットが右 (最も意味のないビット) から挿入されるため、いくつかの反復の後、ゼロ以外のすべてのビットは "数字からシフトアウト」するとゼロになります。

于 2011-03-02T15:24:04.280 に答える
1

の場合signed integer、左端のビットが符号を設定するため、このタイプ要素が持つことができる値の範囲は-2147483648〜2147483647です。正の値から負の値を取得するには、すべてのビットに対してビットを逆にし、その逆も行います。

の場合unsigned integer、左端のビットは追加の値を格納するために使用されます。したがって、このタイプ要素が持つことができる値の範囲は0〜4294967295です。

バイナリ形式でi=1;i = i*2;、値として実行できるのは次のとおりです。

1 // 1 in base 10
10 // 2 in base 10
100 // 4 in base 10
1000
10000
100000
1000000
10000000
100000000
1000000000
10000000000
100000000000
1000000000000
10000000000000
100000000000000
1000000000000000
10000000000000000
100000000000000000
1000000000000000000
10000000000000000000
100000000000000000000
1000000000000000000000
10000000000000000000000
100000000000000000000000
1000000000000000000000000
10000000000000000000000000
100000000000000000000000000
1000000000000000000000000000
10000000000000000000000000000
100000000000000000000000000000
1000000000000000000000000000000 // 1073741824 in base 10
10000000000000000000000000000000 // 2147483648 in base 10 

while (i > 0) {ここで、:のようなループがありi、前述のように動作する場合、0になることはないため、無限ループになります。オーバーフローは発生しますが、プログラムにブレーキはかかりません。引き続き実行されます。

変数iが符号付きの場合(デフォルト)、c=32整数10000000000000000000000000000000が-2147483648と評価され、つまり。として出力され< 0ます。ただし、この場合、出力はわかりません。

それは学業であるため、当然のことながら、教師は問題を選択しました。そこでは、提供されたコードを実行することから何も結論付けることができません。これは、下にある型がどのように格納されているか、および符号付き型と符号なし型の違いを知ってほしいからだと思います。

余計な事実として、Javaには符号なしプリミティブや不変の数値クラスがありません。それらを持たないことは、場合によっては苦痛になる可能性があります。間違いなく便利なキーワードです。

于 2011-03-02T15:59:52.263 に答える
1

符号なしの値はオーバーフローしません。実際、それらはラップアラウンドすることが保証され、定義されています。

于 2011-03-02T15:39:16.290 に答える
0

私はずっと署名されていません。ある時点で、オーバーフロー (または、より明確になる場合はラップアラウンド) して正確に 0 になり、負になることはありません。

于 2011-03-02T15:23:49.847 に答える