for
-loop条件で1つではなく2つの変数をインクリメントしたいと思います。
だから次のようなもの:
for (int i = 0; i != 5; ++i and ++j)
do_something(i, j);
これの構文は何ですか?
回答:
一般的なイディオムは、両方のオペランドを評価して2番目のオペランドを返すコンマ演算子を使用することです。したがって:
for(int i = 0; i != 5; ++i,++j)
do_something(i,j);
現在それを書いているので、コメンターはそれが実際にはfor文の特別な構文糖であり、コンマ演算子ではないことを示唆しました。GCCで次のように確認しました。
int i=0;
int a=5;
int x=0;
for(i; i<5; x=i++,a++){
printf("i=%d a=%d x=%d\n",i,a,x);
}
xがaの元の値を取得することを期待していたので、xに対して5、6、7 ..が表示されているはずです。私が手に入れたのはこれ
i=0 a=5 x=0
i=1 a=6 x=0
i=2 a=7 x=1
i=3 a=8 x=2
i=4 a=9 x=3
ただし、式を括弧で囲んでパーサーにコンマ演算子を実際に表示させると、次のようになります。
int main(){
int i=0;
int a=5;
int x=0;
for(i=0; i<5; x=(i++,a++)){
printf("i=%d a=%d x=%d\n",i,a,x);
}
}
i=0 a=5 x=0
i=1 a=6 x=5
i=2 a=7 x=6
i=3 a=8 x=7
i=4 a=9 x=8
最初は、これはコンマ演算子として動作していないことを示していると思いましたが、結局のところ、これは単なる優先順位の問題です-コンマ演算子には 優先順位最も低いため、式x = i ++、a ++は事実上(x = i ++)、a ++として解析
すべてのコメントをありがとう、それは興味深い学習体験であり、私は長年Cを使用しています!
これを試して
for(int i = 0; i != 5; ++i, ++j)
do_something(i,j);
for( ; ; ((++i), (++j)) )
for(int i = 0; i != 5; (++i)) {
。余分な括弧は、コンパイラをだまして「インクリメント」操作ではないと考えさせます。
それをしないようにしてください!
http://www.research.att.com/~bs/JSF-AV-rules.pdfから:
AVルール199
forループのインクリメント式は、単一のループパラメーターをループの次の値に変更する以外のアクションは実行しません。根拠:読みやすさ。
ここに来て、FORループのインクリメント句に2番目のインデックスをコード化する方法を思い出しました。これは、主に、C ++で記述された別のプロジェクトに組み込んだサンプルでそれを観察することで実行できることを知っていました。
今日、私はC#で作業していますが、FORステートメントはすべてのプログラミングで最も古い制御構造の1つであるため、この点についても同じ規則に従うと確信しました。ありがたいことに、私は最近、古いCプログラムの1つでのFORループの動作を正確に文書化するために数日間費やしましたが、これらの研究が今日のC#の問題、特に2番目のインデックス変数の動作に適用されるレッスンを保持していることにすぐに気付きました。
気を緩める人のために、以下は私の観察の要約です。[ローカル]ウィンドウで変数を注意深く観察することにより、今日起こっているすべてのことが、C#FORステートメントがCまたはC ++ FORステートメントとまったく同じように動作するという私の期待を裏付けました。
ループが終了してもインデックス変数のいずれかがスコープ内にある場合、真のインデックス変数の場合、その値はループを停止するしきい値よりも1つ高くなります。同様に、たとえば、ループに入る前に2番目の変数がゼロに初期化されている場合、最後の値は反復カウントになります。これは、増加ではなく増加(++)であり、ループの本体はその値を変更します。
squelartに同意します。2つの変数をインクリメントすることは、特にそれらの1つだけをテストする場合に、バグが発生しやすくなります。
これは、これを行うための読みやすい方法です。
int j = 0;
for(int i = 0; i < 5; ++i) {
do_something(i, j);
++j;
}
For
ループは、ループが1つの増加/減少変数で実行される場合を対象としています。その他の変数については、ループで変更します。
に関連付ける必要j
がある場合はi
、元の変数をそのままにして追加してみi
ませんか?
for(int i = 0; i < 5; ++i) {
do_something(i,a+i);
}
ロジックがより複雑な場合(たとえば、実際に複数の変数を監視する必要がある場合)、while
ループを使用します。
int main(){
int i=0;
int a=0;
for(i;i<5;i++,a++){
printf("%d %d\n",a,i);
}
}
i
、a
ローカルにしないことのポイントは何ですか?
数学を使用します。2つの演算が数学的にループの繰り返しに依存している場合は、どうして計算しないのですか?
int i, j;//That have some meaningful values in them?
for( int counter = 0; counter < count_max; ++counter )
do_something (counter+i, counter+j);
または、より具体的にはOPの例を参照します。
for(int i = 0; i != 5; ++i)
do_something(i, j+i);
特に、値で関数に渡す場合、必要な機能を正確に実行する必要があります。