文書の過去の版を表示しています。


3-8 while

条件式がわかったのでいよいよ制御文の本体に入ります。まず最初は「繰り返し処理」です。

Arduinoでは、宣言部→setup部→loop部の順にプログラムが実行された後、loop部を無限に繰り返す処理が実行されます。
loop部の繰り返しは条件に関係なく必ず実行されますが、そのloop部の中で、“特定の条件が成立する時だけ、同じ処理を繰り返したい時”に使われるのが「繰り返し処理」です。

本資料では、よく使われる繰り返し処理「while」と「for」の解説をします。
まずは「while」からいってみましょう!

while( 繰り返し処理をするための条件式をここに書く ){
    条件が成立しているときに繰り返したい処理をここに書く
    処理は何行書いてもOK
}

さっそく解説していきます。
 
1行目:
 whileの後ろの( )内に条件式を書きます。
 この条件式が成立している間、while文内部の処理を繰り返し続けます。
 while文の内部は、( )の後ろの「{」から4行目の「}」までの間です。
 
2~3行目:
 ここは{ }で括られた、while文の内部です。
 ここに、条件式が成立しているときに繰り返したい処理を書きます。
 処理は何行でも、必要なだけ書いてOKです。
 この内部に更に別の繰り返し処理や分岐処理を書いて、入れ子状にすることもできます。
 繰り返したい処理とは別に、while文を抜けるための処理も用意しておく必要があります。
 制御文の中身の行は、行頭にインデントを入れておきましょう。
 そうすることで、どこからどこまでがどの制御文の中身かが一目でわかります。
 
4行目:
 波かっこ閉じによって、このwhile文は終了します。
 while文の条件式が不成立だった、或いはwhile文の中身を繰り返処理する中で、成立していた式が不成立になった場合、while文は終了し5行目から次の処理が実行されます。

サンプルコード3-8_while.inoを開いてください。

void setup() {
  Serial.begin(9600);
  //シリアルモニタで結果を見たいので、シリアル通信を開始します
}
void loop() {
  int count = 0;//このcountは、while文の条件式に使うための変数です

  while(count < 10){ 
    //今回の条件は「countが10未満ならwhileを繰り返す」です 
    
    Serial.println("えりんぎ稟議");//モニタに文字列を表示

    count = count + 1; //countに1を足します

    Serial.print("現在");
    Serial.print(count);
    Serial.println("回目の処理だよ");
    //現在何回目の処理かを、↑の3行でシリアルモニタに表示します

    delay(1000);//1秒待機します
  }

  Serial.println("whileを抜けました。loop部の先頭に戻ります");
  delay(5000);//5秒待機します
}

動作確認

とりあえず動作確認してみましょう!
このプログラムをArduinoに書き込むと、シリアルモニタに

「えりんぎ稟議」
「現在XX回目の処理だよ」

の2行がだいたい1秒間隔で表示されます。
「現在XX回目~」の「XX」は1~10までで1回ずつ増え、10回目を表示した後、

「whileを抜けました。loop部の先頭に戻ります」

が表示され、約5秒経過した後「現在1回目~」から再度同じ動作が実行されます。

コード解説

続いてプログラムの解説です。

1巡目
void setup() {
  Serial.begin(9600);
  //シリアルモニタで結果を見たいので、シリアル通信を開始します
}

1~4行目:
 setup部でシリアル通信の設定・初期化をしています。

int count = 0;//このcountは、while文の条件式に使うための変数です

6行目:
 int型の変数countを宣言し、中身に「0」を入れました。
 コメントにも書いてある通り、このcountはwhile文の条件式に使うための変数です。
 今回のプログラムの仕様上、このcountに入る最小の値は「0」、最大の値は「10」です。
 なのでデータ型にはintを採用しています。

while(count < 10){

8行目:
 お待ちかねのwhile文です!まずは条件判定です。
 今回の条件式は(count < 10)です。
 この意味は 「変数countの中身が10未満である間は、while文の中身を繰り返す」 です。
 先ほど変数countの中身には0を代入しました。
 なので (count < 10) は、今回の条件では (0 < 10) となり、「0」は「10未満」なので、この条件式は成立している(true)と言えます。
 条件式が成立したので、while文の中身に突入し、これを実行します。

Serial.println("えりんぎ稟議");//モニタに文字列を表示

11行目:
 文字列「えりんぎ稟議」をシリアルモニタに表示する命令です。

count = count + 1; //countに1を足します

13行目:
 変数countに1を足します。これにより、countの中身は「1」になりました。
 このwhile文は、「whileの中身の処理を10回繰り返す」ことを目的としています。
 そのためには、「今何回目の処理まで終わっているか」を、プログラム内のどこかに記憶させておく必要があります。
 その役割を果たすのが、変数countです。
 この行でcountに1を足すことで、「今1回処理をしました!」ということをcount内に数値という形で蓄積・記憶させます。
 この処理を忘れると、countの中身はずっと0のまま=永遠にwhile文を繰り返し続けることになってしまいます。

Serial.print("現在");
Serial.print(count);
Serial.println("回目の処理だよ");

15~17行目:
 シリアルモニタに文字列「現在XX回目の処理だよ」と表示させます。
 「XX回目」の部分は、変数countの中身を表示しています。
 countの中身には「今何回目の処理まで終わっているか」が数値で記憶されています。
 なので、「現在1回目の処理だよ」が表示されるはずです。

delay(1000);//1秒待機します

20行目:
 人間がシリアルモニタを目で追えるよう、1秒待機させます。

  
ここまでがwhile文の中身です。
while文の最後まで来たら、その下のプログラム…ではなく、while文の先頭に戻ります
このプログラムではwhile文の先頭は8行目です。
なので8行目に戻り、while文の条件式の判定を再度行います。

2巡目

そんなわけでwhile文2巡目です!
 

while(count < 10){

8行目(2巡目):
 条件式は同じ(count < 10) ですが、1巡目とは1点異なる点があります。
 それは、countの中身が「1」に増えていることです。
 なので、今回の条件式では (1 < 10) が判定にかけられます。
 結果は今回もtrueなので、今回もwhile文の中身を実行していきます。
 ちなみにwhile文は、while文の先頭で条件判定を行うのが特徴です。
 (=文の先頭で判定! → trueなら中身に突入 → 最後尾まで来たらもう一度先頭で判定!)
 今回この資料では触れませんが、文の末尾で条件判定をする「do while」文なんてのもありますので、興味のある方は調べてみてください。

Serial.println("えりんぎ稟議");//モニタに文字列を表示

11行目(2巡目):
 またしても「えりんぎ稟議」がモニタに表示されます🍄💭

count = count + 1; //countに1を足します

13行目(2巡目):
 ここでcountに1を足します。
 「今何回目の処理まで終わっているか」を記憶するcountの中身は1+1=「2」になりました。

Serial.print("現在");
Serial.print(count);
Serial.println("回目の処理だよ");

15~17行目(2巡目):
 countの中身が「2」になっているので、「XX回目」は「2回目」と表示されているはずです。

delay(1000);//1秒待機します

20行目(2巡目):
 1秒待機した後、再びwhile文の先頭に戻ります。
  
  
そんなわけでwhile文の2巡目が無事終了しました。
この処理があと8回、10巡目まで繰り返されます。
8回同じ内容を書き続けるのは書く方も読む方もダルいと思いますので、最後の回、10巡目の終了部分まで一気にショートカットします。

11巡目

そんなわけでwhile文11巡目です!
 

while(count < 10){

8行目(11巡目):
 while文の先頭にやってきました。11回目の条件式の判定です。
 11巡目時点(=10回目の処理終了直後)なのでcountの中身は「10」になっています。
 条件式 (count < 10) は (10 < 10) として判定にかけられますが、「10は10未満」は成立しません!falseです!
 (「なぜ?」と思ってる人は、「未満」と「以下」の違いをググってね!)
 falseなので、このwhile文はこれにて終了です。
 while文の中身は実行せずに、全文すっ飛ばして23行目に移ります。

Serial.println("whileを抜けました。loop部の先頭に戻ります");

23行目:
 シリアルモニタに「whileを抜けました。loop部の先頭に戻ります」が表示されます。
 Arduinoのプログラムの基本を思い出しましょう。
 Arduinoでは、プログラムは常に上から1行ずつ順番に実行されます。
 なので、while文を抜けた後は、while文の下にあるコードが順番に実行されます。

delay(5000);//5秒待機します

24行目:
 delayにより約5秒待機します。
 「長かったwhileを終えてプログラムの末尾まで到達した感動をかみしめてほしい…」
 そんな講師の思いで5秒待機させています。仕様的な意味は特にないです。

}

25行目:
 これにてようやくloop部が終了しました。
 先頭に戻り、loop部のプログラムを最初から再度実行します。
 この解説文の冒頭に戻って、同じことをもう一度繰り返すと思っていただければOKです。

while文は…

  • 特定の条件が成立する時だけ、同じ処理を繰り返したい時 に使われる処理
  • 繰り返す条件や回数を条件式で設定する
  • whileを抜け出すための処理を必ず設定する(忘れると無限ループになる)