if文とfor文を合わせて使う場面は、数多くあると思います。そこで、if文とfor文を合わせて使うときに意識しておきたい3つのことを書いていこうと思います。
組み込みプログラムでは処理速度が優先されます。これらを意識することで、プログラムの処理速度を常に考えながら、プログラミングすることができるようになります。
if文はできる限り、for文の外で使う
ご存知の通り、if文は条件分岐、for文は繰り返し文ですね。組み込みプログラムでは処理速度が優先されることを冒頭で触れました。
処理速度を考えたとき、if文はfor文の外で実行するべきです。for文は繰り返しで何回も同じ処理を実行すしますよね。その中に、if文があると、どうなるかわかりますね。
毎回if文の条件判定が行われるわけです。for文の繰り返す回数が多ければ多いほど、余計な判定をするので、処理時間がかかってしまいます。
1回1回の判定にかかる時間はわずかかもしれませんが、このわずかも蓄積されたら大きなロスになりえます。組み込みマイコンでは1/1000秒から50/1000秒の世界ですので、 わずかな時間ロスが大きな問題を引き起こす可能性もあります。
したがって、同じif文条件で済むのなら、for文の中で処理するのではなく、for文の外で先に条件判定をやってしまってから、繰り返し処理を行うようにプログラミングするように意識しましょう。
イメージが付きにくいかもしれませんが、例えば、こんなプログラムです。
#include <stdio.h> void main(void) { int a, b; int i; int ex[100]; a = 2; b = 1; for (i = 0; i < 100; i++) { if (a == b) { ex[i] = i; } } }
プログラム自体に意味はありません。aとbが等しければ、配列exに要素番号を入れるというものです。わざわざfor文の中で、aとbの比較をする必要ないですよね?こういうのは、if文をfor文の外に出して、
#include <stdio.h> void main(void) { int a, b; int i; int ex[100]; a = 2; b = 1; if (a == b) { for (i = 0; i < 100; i++) { ex[i] = i; } } }
とすべきです。aとbが等しくなかったら、何もする必要ありませんよね。これを先のようにfor文の中にif文を入れてしまうと、何も処理をする必要がないのに、無駄に繰り返し文を実行してしまいます。
これは非常にもったいないです。仮にaとbが等しくてもです。等しくても先の例ではif文の条件判定が無駄に実行されてしまいます。
したがって、こういうプログラムにならないように、意識してプログラムを書きましょう。
if文をfor文内で使うときは、if~elseのみにする
先ほど、if文はfor文の外で実行すべきことはお話しました。しかし、いつもそうできるとは限らないですよね。
for文で繰り返されて値が変わるものがif文の条件になっている場合です。この場合は、どうやったって、for文の中にif文を書くしかありません。
ただし、できる限り、条件の分岐はない方がよいのは言うまでもありませんね。要するに、if~elseだけにすることです。else ifをたくさんつけるとそれだけ繰り返し文の中での条件判定処理が増えるので、プログラムが重たくなります。
代表的なものとしては、配列内で最大値と最小値を取ってくるようなプログラムでしょうか?
配列の先頭から順番にアクセスしていき、保持している値よりも大きければ、新たに確保する値を更新して、最終的に保持した値が配列内の最大値となるので、そのようにプログラミングするという感じですね。最小値の場合は、比較時に小さい値を保持すれば、後の処理は最大値の取得と同じです。
#include <stdio.h> void main(void) { int max, min; int i; int ex[10] = {5, 6, 1, 12, 64, -123, -1, 301, 0, 42}; max = -32768; min = 32767; for (i = 0; i < 10; i++) { if (max < ex[i]) { max = ex[i]; } if (min > ex[i]) { min = ex[i]; } } }
こんな感じですかね。for文の中にif文があるのがわかりますね。最大値と最小値を取得するため、if文が2回出て来ていますが、if文自体は干渉しあっていないことがわかると思います。
例ではelse文なしで済んでいます。実際には、なかなかスムーズにプログラミングができないかもしれませんが、処理の負担を意識することは、特に、組み込みマイコンでは大事だと思います。
if文とfor文の始めと終わりがわかるようにしておく
if文とfor文の始めと終わりをわかるようにしておくと、後でプログラムを追いかけるときもスムーズにできます。何でもないようなことかもしれませんが、意外と大事です。
そんなことしなくても、画面見ればわかるだろ?
と言うかもしれませんが、それは、プログラムが画面内に収まっていればの話です。
実際のプログラムは、1画面で収まることはほとんどありません。下手に分割して関数を作っても、かえってプログラムの流れがわかりにくくなってしまいます。
if文やfor文内の処理が分割できるとも限りません。なので、if文やfor文などの開始と終了をわかりやすくしておくほうがいいのです。
インデント(字下げ)をして、わかるようにするようにするのですが、結局、画面からif文やfor文などを書いている始めのプログラムが切れてしまったら、わからなくなってしまいます。
これは、プログラムにミスがあったときに行うデバッグ作業やプログラムのアップデート等で編集するようなとき、スムーズにプログラムを把握する必要があります。
それは人が作ったプログラムかもしれません。自分が作ったプログラムならば、ある程度わかるでしょうが、人の作ったプログラムはそう簡単に理解できません。
そこで、必要となるのが、コメント文です。これをif文やfor文など、あらゆるところに、記載していきます。理想は1かたまりの処理ごとに記載することです。
あまりにも長いif文やfor文の場合には、最後の「}」の後ろに/* end for */というような工夫をしておけば、ここがfor文の最後だな。というのが一目でわかります。
処理速度の向上にはなりませんが、プログラムのメンテナンスのことも考えて、プログラミングすることも大事なことです。
数年前の話を持ち出されることも結構ありますので、せめて自分の書いたプログラムだけでも、後から見てわかるようにしておくように意識してみてください。
そうすると、プログラムを書く前にコメントをつけるという習慣が生まれてきますよ。
まとめ
if文とfor文を合わせて使うときの3つの意識すべきことを紹介しました。
当たり前のようですが、意外と出来ていないので意識して欲しいと思います。
最近のパソコンの性能がよくなっているので、組み込みマイコンのプログラムをしないと、あまり処理速度を意識しないでしょうが、通常のWindowsアプリケーションなどでも必要と思います。
if文とfor文だけでなく、他の文との組み合わせのときでも、動作に変わりがないなら、先に実行しておいたほうが効率がいいものはないかを考えて、プログラミングをしてほしいと思います。
コメント文は書くのが面倒なのと、テストしているとプログラムがコロコロ変わるので、どうしても後回しになりがちです。究極は何も書いていない。と言うこともありますし、書いていても途中段階のままでかえって混乱するものもあります。
始めて、そのプログラムを読むプログラマーにとって、コメント文はプログラムを理解するうえで、非常に助けになります。理解する時間が短ければ、短いほど、その人がやらないといけない課題に早く着手でき、結果としてアウトプットが早くなります。
したがって、コメントだからと手を抜かずにしっかりと書いてほしいと思います。