forステートメントの評価順序
みなさん、forステートメントの処理順序って理解されていますか?
例えばC言語を例に採ります。
for ( 式1; 式2; 式3 ) { 処理1}最初に式1が評価されます。主に、int i = 0;といったループに利用される変数の初期化処理を行いますね。
次に式2が評価されます。式2は、i < 10; といったループを実行するかどうかを判定するための条件式が入りますね。
そして式2が真(TRUE、つまり0以上)ならば処理1が実行されますし、
式2が偽(FALSE、つまり0)ならばこのforステートメントは抜けます。
これで1回目のループ処理は終わります。
さて、お次は2回目のループに入ります。
私は、1回目の処理1が実行された後の動きは次のようになると思っていました。
1回目の処理が終わった後、式2が評価されて、式2が真ならば処理1が実行され、式2が偽ならばこのforステートメントは抜ける。つまり、forステートメントは次のように処理される。式1→式2→処理1→式2→式3→処理1→式2・・・
しかしこれは誤りのようです。
microsoftのC の for ステートメントにはforステートメントを
for ( init-expression ; cond-expression ; loop-expression ) statementと定義した後に次のように記載されています。
cond-expression が真 (0 以外) のときは、statement が実行されます。oop-expression を指定しているときは、次にそれが評価されます。loop-expression はそれぞれのくり返しを実行する前に評価されます。この式には型の制限がありません。loop-expression は、副作用も順番に処理されます。処理が終わったら、ステップ 2 に戻ります。
またC#については、C#の言語仕様 for ステートメントに記載されています。同様に、
for ( for-initializer ; for-condition ; for-iterator ) embedded-statementと定義した後に次のように記載されています。
for-condition が存在しない場合、またはその評価が true の場合、制御は埋め込みステートメントに移ります。制御が埋め込みステートメントの終了点に到達すると (通常は continue ステートメントの実行から)、for-iterator 式がある場合は順に評価され、上のステップの for-condition の評価から次の反復が実行されます。
なのでC言語系(C、C++、C#)については次のように処理されると思われます。
1回目の処理が終わった後、式3が評価されて、式2が真ならば処理1が実行され、式2が偽ならばこのforステートメントは抜ける。つまり、forステートメントは次のように処理される。式1→式2→処理1→式3→式2→処理1→式3→式2→処理1→式3・・・
ウェブ上にあるループ処理をいくつか漁ってみましたが、この手の記述にはたどり着けなかったです。もしかして私は間違っていますかね??もし間違っているようでしたらご指摘頂けると幸いに存じます。
追記
今日はこれで痛い目に遭いました。
1: CList cList;
2: for (POSITION pos = cList.GetHeadPosition(); pos != NULL; cList.GetNext(pos))
3: {
4: DWORD dwVal = cList.GetAt(pos);
5: if (dwVal == 1) {
6: cList.RemoveAt(pos);
7: pos = cList.GetHeadPosition();
8: }
9:}
としていたら、7行目でposがNULLとなってしまい、2行目のGetNext()でGPFですわ。
2行目のpos != NULLでガードできていると思ったのに・・・。
Comments