reverse for loopの私の最初の試みは、何かをn回行います:
for ( unsigned int i = n-1; i >= 0; i-- ) {
...
}
この失敗では、符号なし算術i
は常にゼロ以上であることが保証されているため、ループ条件は常に真になります。幸いなことに、gccコンパイラは、ループが無限に実行されている理由を疑問に思う前に、「無意味な比較」について警告しました。
この問題を解決するエレガントな方法を探しています。
何か案は?ありがとう:)
どうですか:
for (unsigned i = n ; i-- > 0 ; )
{
// do stuff with i
}
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;
...
}
for ( unsigned int i = n; i != 0; i-- ) {
// do something with i - 1
...
}
CだけでなくC++を使用する場合、!=を使用することは、イテレータの使用に切り替えるときに慣れる良い習慣であることに注意してください(<=などは使用できない場合があります)。
なぜ単純ではない:
unsigned int i = n;
while(i--)
{
// use i
}
これは、質問の本文に列挙されているすべての要件を満たしています。コードレビューに失敗したり、コーディング標準に違反したりする可能性のあるものは使用しません。私が見ることができる唯一の異論は、OPが本当にfor
ループを主張し、i =(n-1).. 0を生成する直接的な方法ではない場合です。
for ( unsigned int i = n; i > 0; i-- ) {
...
i-1 //wherever you've been using i
}
使用する傾向がある
for ( unsigned int i = n; i > 0; ) {
--i;
...
}
これは、skizzの答えとほぼ同じであり(最終的な不必要なデクリメントを逃しますが、コンパイラはそれを最適化する必要があります)、実際にコードレビューに合格します。私が取り組まなければならなかったすべてのコーディング標準には、条件付きルールに変化がありませんでした。
たぶんこのように?私見は明確で読みやすい。暗黙的に既知の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 );
for (unsigned int i = n-1; i<(unsigned int)-1; i--)
OK、その「あいまいなリング演算」。
または、n-1から0へのインデックス付けが必要な場合は、unsigned int
のラッピング動作に依存できます。
for(unsigned int i = n-1; i < n; i--) {
...
}
for ( unsigned int i = n; i > 0; i-- ) {
unsigned int x = i - 1;
// do whatever you want with x
}
確かにエレガントではありませんが、機能します。
このオプションに言及する唯一の理由は、リストに表示されていないためです。
for ( unsigned int i = n-1; i < n; i-- ) {
...
}
完全に直感に反しますが、機能します。動作する理由は、0から1を引くと、符号なし整数で表現できる最大数が得られるためです。
一般に、特に減算の場合、符号なし整数とアーティメットを使用するのは良い考えではないと思います。
簡単、-1で停止:
for( unsigned int i = n; i != -1; --i )
{
/* do stuff with i */
}
編集:なぜこれがダウン投票されているのか分かりません。それは機能し、上記のどれよりも簡単で明白です。
for ( unsigned int i = n; i > 0; i-- ) {
...
}
正常に動作するはずです。 i
変数を配列のインデックスとして使用する必要がある場合は、次のようにします。
array[i-1];
うんオプションは次のとおりです。
i=0
はブレーク条件として-iが0に達するとループは実行されないため、i=0
ループが終了した後。for ( unsigned int i = n-1; i > 0; i-- ) {
doStuff(i);
}
doStuff(0);
i=0
およびbreak
out。ループ内でiの値を2回テストしているため、お勧めしません。また、ループ内でブレークを使用することは、一般的に悪い習慣と見なされます。for ( unsigned int i = n-1; i >= 0; i-- ) {
doStuff(i);
if (i=0) break;
}
unsigned index;
for (unsigned i=0; i<n; i++)
{
index = n-1 - i; // {i == 0..n-1} => {index == n-1..0}
}
これはループの標準ではないため、代わりにwhileループを使用します。
unsigned int i = n - 1;
while (1)
{
/* do stuff with i */
if (i == 0)
{
break;
}
i--;
}
これはテストされていませんが、次のことを行うことができます:
for (unsigned int i, j = 0; j < n; i = (n - ++j)) {
/* do stuff with i */
}
2つの変数を使用して、1つはpをカウントし、もう1つは配列インデックスに使用します。
unsigned int Index = MAX - 1;
unsigned int Counter;
for(Counter = 0; Counter < MAX; Counter++)
{
// Use Index
Index--;
}