67

n 回何かを行う逆の for ループの私の最初の試みは、次のようなものでした。

for ( unsigned int i = n-1; i >= 0; i-- ) {
    ...     
}

これは、符号なし算術演算が常にゼロ以上であることが保証されているため失敗します。したがって、ループ条件は常に真になります。幸いなことに、なぜループが無限に実行されるのか疑問に思う前に、gcc コンパイラは「無意味な比較」について警告してくれました。 i


次のことを念頭に置いて、この問題を解決するエレガントな方法を探しています。

  1. これは逆方向の for ループである必要があります。
  2. ループ インデックスは符号なしにする必要があります。
  3. n は符号なし定数です。
  4. 符号なし整数の「あいまいな」環算術に基づくべきではありません。

何か案は?ありがとう :)

4

20 に答える 20

15
for ( unsigned int loopIndex = n; loopIndex > 0; --loopIndex ) {
    unsigned int i = loopIndex - 1;
    ...
} 

また

for ( unsigned int loopIndex = 0; loopIndex < n; ++loopIndex ) {
    unsigned int i = n - loopIndex - 1;
    ...
} 
于 2009-03-20T11:30:53.297 に答える
11
for ( unsigned int i = n; i != 0; i-- ) {
    // do something with i - 1
    ...     
}

C と同様に C++ を使用する場合、<= などを使用できない可能性がある反復子の使用に切り替えるときに、!= を使用することをお勧めします。

于 2009-03-20T11:29:46.280 に答える
9

私は使いがちです

 for ( unsigned int i = n; i > 0; )  {
    --i;
    ...     
 }

これはskizzの答えとほぼ同じであり(最後の不要なデクリメントを見逃しますが、コンパイラはそれを最適化する必要があります)、実際にはコードレビューに合格します。私が使用しなければならなかったすべてのコーディング標準には、条件付き規則に変化がありませんでした。

于 2009-03-20T11:44:44.650 に答える
8
for ( unsigned int i = n; i > 0; i-- ) {
    ...  
    i-1 //wherever you've been using i   
}
于 2009-03-20T11:30:10.210 に答える
5

多分このように?私見その明確で読みやすい。if(n> = 1)が何らかの形で暗黙的に知られている場合は、省略できます。

if(n>=1) {
    // Start the loop at last index
    unsigned int i = n-1;
    do {
       // a plus: you can use i, not i-1 here
    } while( i-- != 0 );
}

別のバージョン:

if(n>=1) {
    unsigned int i = n;
    do {
       i--;

    } while( i != 0 );
}

ifステートメントのない最初のコードは次のようになります。

unsigned int i = n-1;
do {

} while( i-- != 0 );
于 2009-03-20T11:52:18.143 に答える
4
for (unsigned int i = n-1; i<(unsigned int)-1; i--)

OK、その「あいまいなリング算術」。

于 2009-03-20T12:34:38.027 に答える
3
for ( unsigned int i = n; i > 0; i-- ) {
    unsigned int x = i - 1;
    // do whatever you want with x    
}

確かにエレガントではありませんが、機能します。

于 2009-03-20T11:32:00.547 に答える
2

簡単です。-1 で停止します。

for( unsigned int i = n; i != -1; --i )
{
 /* do stuff with i */
}

編集:なぜこれが反対票を投じているのかわかりません。それは機能し、上記のどの方法よりも単純で明白です。

于 2009-09-06T21:56:26.763 に答える
1
unsigned index;
for (unsigned i=0; i<n; i++)
{
    index = n-1 - i; // {i == 0..n-1} => {index == n-1..0}
}
于 2009-03-20T14:20:55.977 に答える
1
for ( unsigned int i = n; i > 0; i-- ) {
    ...     
}

うまくいくはずです。i変数を配列のインデックスとして使用する必要がある場合は、次のようにします。

array[i-1];
于 2009-03-20T11:31:16.120 に答える
0

2 つの変数を使用します。1 つはカウントアップ用で、もう 1 つは配列インデックス用です。

unsigned int Index = MAX - 1;
unsigned int Counter;
for(Counter = 0; Counter < MAX; Counter++)
{
    // Use Index
    Index--;
}
于 2009-03-21T17:15:16.643 に答える
0

これは標準の for ループではないため、おそらく代わりに while ループを使用します。

unsigned int i = n - 1;
while (1)
{
    /* do stuff  with i */

     if (i == 0)
    {
        break;
    }
    i--;
}
于 2009-03-20T12:25:17.517 に答える
0

これはテストされていませんが、次のことができますか?

for (unsigned int i, j = 0; j < n; i = (n - ++j)) {
    /* do stuff with i */
}
于 2009-03-20T12:32:42.710 に答える
-1
for ( unsigned int i = n-1; (n-i) >= 0; i-- ) {
    // n-i will be negative when the loop should stop.
    ...     
}
于 2009-03-20T11:32:49.827 に答える
-6

エズ:

#define unsigned signed

for ( unsigned int i = n-1; i >= 0; i-- ) { ... 
}
于 2009-09-06T22:20:41.120 に答える