目標
同じ処理を繰り返し行う方法に、行う処理を延々と繰り返して記述する方法もあるが、これはさすがに頭が悪い。同じ作業を繰り返すのならば、「○回繰り返せ」や「条件○が成立するまで繰り返せ」などと表現をするのが頭がよい。その意味で、以下には代表的な繰り返しの方法、For 文・while 文・Do 〜 while 文について解説を加える。
For 文
現物を見てもらう方が早い。
《Arduino Sketch のプログラム例》
#define LED 13
void setup(){
pinMode(LED, OUTPUT);
}
void loop(){
for ( int i = 1 ; i <=13 ; i++ ){
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
delay(1000)
}
|
定数 LED を 13 に定義(LEDの接続位置を指定)
setup関数の開始
13番ピンは「出力」に定義
setup関数の定義範囲はここまで
一番外側の無限ループの定義開始
for ループの開始点(以下が繰り返される)
13番ピンを HIGH にあげる。(LEDが点灯)
そのまま 0.1 秒待つ(時間の単位は 1/1000 秒)
13番ピンを LOW にさげる。(LEDが消灯)
そのまま 0.1 秒待つ。
ここが for ループの範囲の終了点。
1秒待つ
無限に繰り返す範囲はここまで
|
for ( int i = 1 ; i <=13 ; i++ ) の意味は以下のようになる。
・i を整数値変数と定義し、その初期値を 1 とする。
・i の値が 13 に等しいか小さいうちはループが回る。
・i の値を 1 ずつ増やす。(インクリメント)
従って、ループの1回目は i の値を 1 として回り、一回りしたところで i の値を 1 増やし i = 2 で2回目のループを回る。i の値を 1 ずつ増やしながら繰り返し、i = 13 でループを回ったら、次の周( i = 14 になる )には入らないでループを抜ける。
|
for ループの書式は次のようになる。
for ( カウンタの初期化 ; 条件式 ; 増分 ){
実行される処理 ;
}
|
多くの場合、カウンタに用いる変数は 整数( int )形式 で、i, j, k 等を用いる。i から使うことは Integer の i を「整数」と定義した Fortran のなごりでもある。条件式の書き方は、= は代入を表すために以下のようになる。
表現 |
意味 |
表現 |
意味 |
a == b |
a = b |
a != b |
a ≠ b |
a > b |
a > b |
a >= b |
a ≧ b |
a < b |
a < b |
a <= b |
a ≦ b |
増分のところには 次の i の値を計算するための計算式 を書く。通常はこった計算式にせずに、インクリメント i++ ( i の値を1ずつ増やす ) を書くことが多い。
実行される処理の部分には複数行の命令を書くことができる。計算式だけでなく、この中にもループが入ったり、条件分岐が入ったりしても良い。
While 文
《Mindstorm NXC のプログラム例》
task main()
{
SetSensorTouch(IN_1);
OnFwd(OUT_AC, 75);
while (true){
if (SENSOR_1 == 1){
OnRev(OUT_AC, 75);
Wait(300);
OnFwd(OUT_A, 75);
Wait(300);
OnFwd(OUT_AC, 75);
}
}
}
|
タスクメインの開始
タッチセンサーを IN_1 に接続したことを宣言
左右のモーターを 75% の出力で回転。前進する。
無限ループの開始
タッチセンサーに触れたときの処理の定義
左右のモーターを 75% の出力で逆転
0.3 秒後退する。
右のモーターを正方向に回転
0.3 秒間ターンする
左右のモーターを 75% の出力で正転し前進する
タッチセンサーに触れたときの処理はここまで
無限ループの範囲はここまで
タスクメインの終了(ここまではこない)
|
while(true){ 処理 } の意味は、{}内部でエラー ( false ) が発生しない( true )の間は処理を繰り返す。この場合、false になる場合はないので無限に繰り返すことになる。
|
while ループの書式は次のようになる。
while ( 条件式 ){
実行される処理 ;
}
|
実行される処理で記述された命令群は条件式が「真」である間繰り返し実行される。
do 〜 while 文
《Arduino Sketch のプログラム例》
for ループのプログラム例を do 〜 while 文 で書き直した。
#define LED 13
void setup(){
pinMode(LED, OUTPUT);
}
void loop(){
int i = 1 ;
do {
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
i++ ;
} while ( i <=13 ) ;
delay(1000)
}
|
定数 LED を 13 に定義(LEDの接続位置を指定)
setup関数の開始
13番ピンは「出力」に定義
setup関数の定義範囲はここまで
一番外側の無限ループの定義開始
カウンタ用変数 i を定義
do ループの開始点(以下が繰り返される)
13番ピンを HIGH にあげる。(LEDが点灯)
そのまま 0.1 秒待つ(時間の単位は 1/1000 秒)
13番ピンを LOW にさげる。(LEDが消灯)
そのまま 0.1 秒待つ。
カウンタ i を1上げる。
i が 13 以下 の時は開始点に戻る。
1秒待つ
無限に繰り返す範囲はここまで
|
do 〜 while 文の書式は次のようになる。
do {
実行される処理 ;
} while ( 終了条件 );
|
do 〜 while 文のポイントは、ループの終了条件の記述にある。上の例のように、回数を数えながら、その回数が13になったら終了するような場合は、数を数えるカウンタの役割をする変数とカウンタの数を1上げる(=数を数える)命令(=インクリメント)が必要となる。回数を数えない場合(例 アナログ入力が特定の値よりも小さい など)は終了条件を記述するだけで良い。
まとめ
ループの使用はプログラムがわかりにくくなる最初の原因となる。処理を頭の中でシミュレートしながら、数回ループを回す(トレースする)とイメージができてくるが、これにはある程度の慣れが必要なようだ。
使用するループの選択は、数を数える必要があるか否かで判断する。何回回すかわかっている場合は For ループだが、多くの場合は do 〜 while で処理をする方が多い。
いずれにしても十分に使い込むことが大切だ。
|