12

N から 0 (包括的) に移動する必要があるループがあります。私のi変数は、size_t通常は符号なしの型です。現在、次のコードを使用しています。

for (size_t i = N; i != (size_t) -1; --i) {
    ...
}

あれは正しいですか?状態を処理するためのより良い方法はありますか?

ありがとう、

ヴィンセント。

4

8 に答える 8

7

はい、それは正しく、非常に一般的なアプローチです。私はそれを変更することは考えません。

符号なし整数型の2^N算術演算では、モジュロ演算 (Nは型の値のビット数) を使用することが保証されており、オーバーフロー時の動作は明確に定義されています。結果は、の倍数を加算または減算することによって範囲0に変換されます(つまり、モジュロ演算)。2^N - 12^N2^N

-1符号なし整数型 (そのうちのsize_t1 つ) に変換され2^N - 1ます。--また、符号なしの型に対してモジュロ2^N演算を使用するため、値を持つ符号なしの型0は にデクリメントされ2^N - 1ます。ループ終了条件は正しいです。

于 2010-08-14T18:52:41.180 に答える
5

各反復の開始時にテストを配置するのに便利な場所があるからといっforて、それを使用する必要があるわけではありません。Nから0までを処理するは、少なくとも最大値の処理に関心がある場合は、テストを最後に行う必要があります。便利なことに、テストを間違った場所に置くことに夢中にならないようにしてください。

for (size_t i = N;; --i) {
    ...
    if (i == 0) break;
}

ido-whileループも機能しますが、その場合はさらに、ループのスコープをあきらめることになります。

于 2010-08-14T23:47:27.790 に答える
5

個人的には、別のループ構成を使用するだけですが、それぞれに独自のものがあります。

size_t i = N;
do {
    ...
} while (i --> 0);

(ループ条件として使用することもできますが、 「演算子」(i--)を使用する機会を決して逃してはなりません)。-->

于 2010-08-14T21:36:44.067 に答える
4

これを使用できます:

for (size_t i = n + 1; i-- > 0;)
{
}

それが役立つことを願っています。

于 2010-08-14T17:58:13.210 に答える
3
for ( size_t i = N ; i <= N ; i-- ) { .... }

size_t は unsigned int であるため、これで十分です。unsigned int は 32 ビットです。変数 i の値が 0 の場合、ループで条件を実行します。i-- を実行すると、コンピュータは

 00000000000000000000000000000000
-00000000000000000000000000000001

これにより、明らかなオーバーフローが発生し、値は 111111111...1 になります。符号付き 2 の補数の整数の場合、この値は明らかに負です。ただし、i の型は unsigned int であるため、コンピューターは 111111...1 を非常に大きな正の値と解釈します。

したがって、いくつかのオプションがあります。

1) 上記のようにして、オーバーフローが発生したときにループを終了させます。

2) ループを i = 0 から i <= N まで実行しますが、ループ内のどこでも i の代わりに (Ni) を使用します。たとえば、myArray[i] は myArray[Ni] になります (N の値が実際に表すものに応じて 1 ずつオフになります)。

3) for ループの条件で単項 -- 演算子の優先順位を利用するようにします。別のユーザーが投稿したように、

for ( size_t i = N + 1 ; i-- > 0 ; ) { ... }

これにより、i が N+1 に設定され、N+1 > 0 という条件がまだ成立しているかどうかが確認されます。ただし、i-- には副作用があるため、i の値は i = N に減分されます。i = 1 になるまで続けます。条件はテストになります。1 > 0 が真であり、副作用が発生します。の場合、i = 0 で実行されます。

于 2010-08-14T18:37:25.277 に答える
1

2 番目の変数をループ カウンターとして使用して、反復の範囲を将来のレビュー担当者に明確にすることができます。

for (size_t j=0, i=N; j<=N; ++j, --i) {
    // code here ignores j and uses i which runs from N to 0
    ...
}
于 2010-08-14T18:50:38.440 に答える
1
for (i=N; i+1; i--)
于 2010-08-15T18:23:26.683 に答える
0

符号なし整数はゼロから減分されると最大値になるため、次のことを試すことができますが、その最大値よりも小さい場合に限ります (これがUBNの場合は誰かが私を修正してください)。

for ( size_t i = N; i <= N; i-- ) { /* ... */ }
于 2010-08-14T18:27:02.730 に答える