ぱぴブログ

さんたろのブログ

ゲーム開発が好きな人のひとりごと

do while文におけるcontinue

do while文やcontinueはわかりにくいため使用を避けるべき
と耳にすることがある。

しかし、使った方がいい場面も多々あると思う。
今回はdo while文のcontinueの挙動について考えていく。
なおコードはC言語で書かれているが、多くの他言語で同じ考えであろう。
 

まずは次のコードを見てほしい

#include <stdio.h>
int main(void){
  int i = 0;

  do{
    printf("\n i = %d: Hello", i);
    if(i == 3) continue;
    printf(" World!");
    i++;
  }while(i < 5);

  printf("ループ終了 i = %d\n", i);
  return 0;
}


期待した実行結果は以下の通りだ

 i = 0: Hello World!
 i = 1: Hello World!
 i = 2: Hello World!
 i = 3: Hello
 i = 4: Hello World!ループ終了 i = 5

iの値が3になったときだけ" World!"と出力せず、
iの値が5になったときにループを抜けるという実行結果を期待したコードである。
しかし実際に動かしてみると無限ループに陥ることがわかる。

do while文内をwhile文で表してみよう

while(i < 5){
  printf("\n i = %d: Hello", i);
  if(i == 3) continue;
  printf(" World!");
  i++;
}

iの値が3であるとき、continueより下の部分は読みこまれずにwhileの判定へ行く。
つまりiがインクリメントされないので永遠とiの値は3のままなのである。

do while文だろうとwhile文だろうと
continueがきたらループの判定に飛ぶ
と覚えておくといいだろう。

今は短いコードなのですぐわかったが、大きなプログラムになると
知らない間にcontinueで動作を飛ばす危険性もあるので十分に注意してほしい。



ここからは蛇足だがインクリメントについて考えよう。

先ほどの無限ループのコード、if文の前にiをインクリメントしてみよう。

while(i < 5){
  printf("\n i = %d: Hello", i);
  i++;
  if(i == 3) continue;
  printf(" World!");
}

実行すると無限ループに陥らずに済んでいることがわかる。

 i = 0: Hello World!
 i = 1: Hello World!
 i = 2: Hello
 i = 3: Hello World!
 i = 4: Hello World!ループ終了 i = 5

しかしWorld!が無い位置がひとつズレてしまっている。
では出力の前にインクリメントしよう。

while(i < 5){
  i++;
  printf("\n i = %d: Hello", i);
  if(i == 3) continue;
  printf(" World!");
}

実行してみると

 i = 1: Hello World!
 i = 2: Hello World!
 i = 3: Hello
 i = 4: Hello World!
 i = 5: Hello World!ループ終了 i = 5

ああしまった。iの値を出力する前にインクリメントしたらだめだ。
でもif文より下に書いたら無限ループに陥る...。
そんなときは条件式でインクリメントしよう。

while(i < 5){
  printf("\n i = %d: Hello", i);
  if(i++ == 3) continue;
  printf(" World!");
}

実行してみると

 i = 0: Hello World!
 i = 1: Hello World!
 i = 2: Hello World!
 i = 3: Hello
 i = 4: Hello World!ループ終了 i = 5

無事できた。繰り返し構文内の条件式でのインクリメント(デクリメント)は
わりと使えるので覚えておこう。
なおi++と++iの違いがわからない人は調べて確実に理解しよう。


最後に次のコードの実行結果を予想してほしい。
実際に実行してみて予想通りならバッチリだ。

#include <stdio.h>
int main(void){
  int i = 0;
  do{
    printf("\ni = %d: Hello", i);
    if(++i == 3) continue;
    printf(" World!");
  }while(i++ < 6);
  printf("\ni = %d: ループ終了\n", i);
  return 0;
}