一定回数の処理をwhile構文とは別の方法で実現してみます。
一定回数処理をするスケッチ
前回の記事では、一定回数処理をするスケッチを、変数とwhile構文を使用して実現しました。前回の記事でも書きましたが、while構文を使用した一定回数処理のスケッチはちょっと読みづらいところがあります。
C/C++言語に限らず、一定回数処理をする、という場面はたくさん出てきますので、while構文よりスッキリ書ける構文が用意されています。今回の記事ではその書き方を習得します。
for文
while構文を使用した一定回数処理のスケッチは以下のような特徴があります。
例えばuint8_t型のcountという変数を使用する場合、最初にcountに数字を入れて、そのcountがある条件を満たしている間、countの値を変化させながら処理を行う、ということをしています。
ところで、このようにwhile構文で一定回数処理をする場合、変数countを書く場所が散らばっていますよね。繰り返し行う「処理」が長い場合、countをどのように書いている場所がこんな感じで離れてしまいます。
そこで、このような処理を行うためにC/C++言語では「for文」という制御構文が用意されています(「制御構文」という言葉を忘れてしまっていたら第22回の記事を確認してください)。
正直、この説明だけではさっぱりわかりませんよね。このfor文は、while構文を使った一定回数繰り返す処理の書き方を習得していればすぐに分かってしまうんです。while構文とfor文は以下のように同じ色の部分が対応しています。
前回の記事で、変数とwhileをうまく使って一定回数処理を繰り返す処理を書きました。その処理をよくよく分析すると、以下のようになっていたんです。
このようにwhile文で書くと、繰り返しのために使用している変数がバラバラの場所に書くことになるので、一ヶ所に集めた方がわかりやすいだろう、ということでfor文があります。
それでは、前回while構文で作成した3回LEDを点滅するスケッチをfor文を使って書き直してみます。おそらく難しいところはないと思いますが、もし???となったら前回の記事と今回の記事をじっくり読み直してスケッチを比較してみてください。
/*
* キッチンタイマー
*
* 内容: スイッチ、LED、スピーカーを使ったキッチンタイマー
* 変更履歴:
* 2019. 8.11: 新規作成
* 2019. 8.15: スタートスイッチ処理を追加
* 2019. 8.17: スイッチ関連の#define追加
* 2019. 9. 8: 点滅回数カウント追加
* 最終的に繰り返し処理をfor文で作成
*/
// 秒を表現するLED関連(青色LED)
#define BYOU_LED 12 // 秒を表現する青色LEDの端子番号
#define BYOU_ON 50 // 秒を表現するLEDをつけている時間 (単位:ミリ秒)
#define BYOU_OFF 1000 - BYOU_ON // 秒を表現するLEDを消している時間 (単位:ミリ秒)
// スタートスイッチ関連
#define SWITCH 23 // スイッチを接続している端子番号
#define SWITCH_OFF 1 // スイッチOFFの時のdigitalReadの値
#define SWITCH_ON 0 // スイッチONの時のdigitalReadの値
// タイマー時間設定(LEDの点滅回数)
#define TIMER_JIKAN 3
void setup() {
// 端子の設定
pinMode(BYOU_LED, OUTPUT); // 青色LED接続端子設定
pinMode(SWITCH, INPUT_PULLUP); // スイッチ接続端子の設定
// スイッチが押されるまで待つ
while(digitalRead(SWITCH) == SWITCH_OFF) {
}
}
void loop() {
// LEDの点滅回数を数えるための変数宣言
uint8_t count;
// TIMER_JIKAN分の回数を数える
for( count=0; count<TIMER_JIKAN; count++) {
// 1秒に1回青色LEDを点滅する
digitalWrite(BYOU_LED, HIGH);
delay(BYOU_ON);
digitalWrite(BYOU_LED, LOW);
delay(BYOU_OFF);
}
// 何もしないで待つ
while( true ) {
}
}
for( ; ; )
for文の説明は以上ですが、ネットでスケッチを調べていると不思議なfor文が出てくることがありますので、その書き方も覚えておきましょう。以下のようなfor文です。
for( ; ; ){
処理1;
処理2;
処理3;
}
for文の中の3つの式に何も書いていないスケッチです。これはArduinoのスケッチに限らず、C/C++言語のプログラムでたまにこのように書く人がいます。
for文の3つの式に何も書かないと、終了する条件がないため、ずっと処理を続けることになります(for文は「継続条件式」に何も書かないと、条件が成立しているとみなされます)。
上のfor文の例では、処理1、処理2、処理3をずっと繰り返します。ずっと繰り返す場合、以下のように書けますが、
while( true ) {
処理1;
処理2;
処理3;
}
for文の方が短く書けるので、for( ; ; )
という書き方を好む方もいるようです。ずっと繰り返す場合、どちらでも構いませんが、このシリーズでは条件が明確であることから
while( true ) {
}
という書き方を採用することにします。
forとwhileの違い
繰り返し処理が実現できる「while」と「for」を習得してきました。
この記事の最初の方で、以下のようにwhileとforは同じ意味、と説明しました。
実は、while構文の中の処理内容、書き方によっては意味が異なってくるケースがあります。そこで、for文の説明の最後に、while文との関係をさらに深掘りしたいと思います。
上の図のように、確かにforとwhileは書き換え可能です。ただ、繰り返し処理の中で変数「count」を使う処理の場合はちょっと様子が異なってきます。
と言われても、この図でも意味は同じになりますよね。
ところが、whileの中身を「count」の処理が最初にくるように書き換えると、意味が異なってきます。
処理を順番に追ってみると、それぞれの繰り返し処理の時のcountの値が異なっています。
他の人が作ったスケッチを参考にする場合、forとwhileの「処理式」の実行タイミングに注意するようにしてみてください。
forの「処理式」はそれぞれの繰り返し処理の最後に実行されます。
一方whileでは「処理式」は自分で書く場所を決めるため、それぞれの繰り返し処理でどこに書かれているか注意するようにしてください。
更新履歴
日付 | 内容 |
---|---|
2019.9.8 | 新規投稿 |
2021.8.24 | 新サイトデザイン対応 |
2022.2.11 | 説明補足 |
2022.2.14 | forとwhileの違い説明補足 |