読者です 読者をやめる 読者になる 読者になる

チラシの裏からうっすら見える外枠の外のメモ書き

新聞に挟まってる硬い紙のチラシの裏からうっすら見える外枠の外に走り書きされたようなものです。思いついたときにふらふらと。

プログラミング - whileとfor

今日は結局プログラミングを教えることがなかったので、代わりにここに書いておこう。

おそらく代わりに誰か教えているだろうし、ここは参考程度に。



それにしても今日も暑かった。

一時的に窓を締め切って扇風機だけで乗り切る必要があったのだが、熱気が動く程度で全く役に立たない。

それぐらい暑い。

あ、ちなみに昨日たっぷり寝たおかげで今日は体が楽だ。




それでは始める


while

プログラミングをしているとき、こんなことはないだろうか。

「この処理を後6回繰り返さないといけないのに、わざわざコピー&ペーストするのは面倒くさいなぁ」

同じ処理をプログラムで記述するのは非常に面倒である。

例えば6回ユーザーに同じ文章を表示するプログラムを作るとしよう。

単純に考えれば、コードは次のようになる。

print("とある文章");
print("とある文章");
print("とある文章");
print("とある文章");
print("とある文章");
print("とある文章");

使用言語:Processing


こう書くとなると、非常に見づらく、何回繰り返したかわかりづらい。

もし、これでわかりづらくないと思うのであれば、153回繰り返したら、それがコメント文なしで見た際に一瞬で何回繰り返したかわかるか試して欲しい。

それでわかるのであればwhileに関しては必要ないかもしれない。

ただ、これはあくまで一人で書いている時だけであって、他人に見せるのであれば絶対にwhileなどを使うべきである。

話を戻すが、繰り返しを簡単にする関数として、"while"がある。

whileがやってくれることは、単純に「条件が"正しければ"繰り返す」というものだ。

早速例を上げてみる。

上のコードを今度はwhileを利用して記述してみよう。

int count = 0; // 繰り返す回数を制御する

while(count < 6){
	print("とある文章");
	count = count + 1;
}

使用言語:Processing


さて、今書いたコードはwhileの条件に次のように記述してある。

「変数countが6未満であれば(繰り返す)」

最初、変数countは0が代入(初期化)されている。よって、whileに到達した際は条件は正しい(真、英語で"true")となる。

条件が真である場合は処理を繰り返すので、早速{}(波括弧)の中の処理を実行する。

つまり、「とある文章」と出力し、変数countに1足すのだ。

上の例ではcountにcountと1を足したものを代入しているが、次の書き方でも良い。

int count = 0; // 変数countを初期化している

count = count + 1;
count += 1;
count++;

使用言語:Processing


今示したものはすべて同じ処理を指している。

どれが使いやすいかは自分で判断してみるといい。


話を戻すと、今の処理で変数countが0から1へと変わった。

変数には基本的に値を複数記録することはできないから、この処理が終わった後に変数countの中は1となる。

次に処理する部分は、波括弧の上、つまりwhileの条件だ。

再び条件を評価する。すると、変数countは1なので、6未満か判断する。

結局のところ、まだ6未満なので波括弧の中は繰り返し行われる。


何度か繰り返すと、変数countはそのうち6が代入されているはずだ。

そうすると、再び条件へ戻ってきた際に、評価結果が真から偽(正しくないこと、英語で"false")になる。

whileは条件が真の間だけ処理を繰り返すので、繰り返しは終了、波括弧より先の処理を行う。


これにより、繰り返しが簡単に、しかもわかりやすく書くことができた。


whileは繰り返すことが手軽にできるのでよく利用されるが、注してもらいたいことがある。

それは、「無限ループ」に陥る可能性があることだ。


無限ループという言葉はプログラミングをしたことがない人でも聞いたことがあるだろうと思う。

ひたすら同じ処理が繰り返されるため、ループが無限に続くことからこう呼ばれている。

プログラミングをしえているうえで厄介になりうるこの無限ループだが、今回説明するこのwhileとforで陥りやすい面倒事である。

whileで無限ループに入るということは、条件が何をどうしても絶対に偽にならないということだ。

例として、波括弧内で条件を変化させる処理を書いていないことや、条件演算子が正しくないなどの理由が挙げられる。

無限ループに陥った場合は、とりあえずソフトを停止させなければならない。

停止の方法は様々あるが、最悪タスクマネージャーから停止させたり、PCの電源を止めたりすることになる。

実行する前にwhileの条件が正しいか、そしてwhile内で条件を変化させる処理を行っているか十分に確認して欲しい。


for

さて、ここまででwhileを説明してきたが、一つ面倒だと思う点はないだろうか。

なければ別にこの内容はすっ飛ばしてもらっても全然構わないのだが、次のような引っ掛かりがあればぜひ見て欲しい。

「わざわざ波括弧内に条件を変化させる処理を書くのは面倒だなぁ」

「繰り返している回数を処理の一部として利用したい」

そう考えていれば、いい関数があります。

ぜひ使って欲しいです。

ただ、この関数はwhileより若干わかりづらいので、whileだけで手一杯であればwhileに慣れるまでforを使うことはおすすめしない。

実際私はwhileがわかっていたがforがわからなかったということがあった。


forはwhileの発展型で、次のように使用する。

for (int count = 0; count < 6; count++){
	print(count + "回目の出力");
}

使用言語:Processing


では、上のコードからforは何をしているか説明しよう。

まず、forの括弧内を分割すると、次の3つに分かれると考えて欲しい。

int count = 0;
count < 6;
count++;

使用言語:Processing


forは;(セミコロン)によって括弧内を分割している。

まずforで行うことは、初期化だ。

int count = 0;という処理をすることで、countという変数に0を代入し、初期化を行っている。

次に、条件を評価する。これはwhileと同じように行う。

今回の場合は変数countが6未満かを確認している。

現在は初期化(0を代入)しただけなので、条件は真、波括弧内の処理へ移る。

さて、ここでcount++はどうしたのかという話になる。

これは、並括弧内の処理が正常に全終了した際に行われる後処理だ。

話を戻すと、count + "回目の出力"と表示する処理が行われている。

countは0が入っているので「0回目の出力」と表示されているはずだ。

0が嫌な人は初期化の際に0を1にするなりして、条件もそれに見合うものに自分で変更して欲しい。


出力が終わったので、先ほど説明した後処理である変数countへ1足すという処理を行う。

さて、次に何をするのか。

それは、もう感のいい方はわかると思うが、条件の評価だ。

その後条件が真であれば再び波括弧内の処理を行い、後処理をしてから再び条件の評価を繰り返す。

条件が偽になった場合は、そこでforが終了する。


さて、これを見てわかった人はいるだろうか。

処理をすべて記号にして、順番をつけると、次のようになる。

for(A;B;C){
	D;
}

使用言語:Processing


1.Aを処理

2.条件Bを評価、評価が真であれば3、偽であればforを抜ける

3.Dを処理

4.Cを処理

5.2へ戻る


このようになっている。

これを利用すれば、whileよりも更に見やすい繰り返しが書ける場合が多い。




さて、ここまででwhileとforを説明してきた。

ここで再び注意すべきことを書く。

先ほど説明したとおり、繰り返し処理は無限ループに陥りやすいので十分注意する必要があることは先ほど書いたとおりだが、更に注意すべきことは、変数と途中でループを抜ける方法、波括弧の不要となる場合についてだ。

まずは変数について。

前回の変数の説明で、特定の場合で変数がなかったことにされるという話をした。

変数は大域変数と、局所変数という2種類に分類される。


大域変数とは、プログラム内のどこででも利用できる変数のことだ。

それに対し局所変数はある部分でしか利用できない変数だ。

ある部分とは、ifの中、while/forなどの中で"宣言された"変数だ。

それらの変数はその処理内でしか利用できず、波括弧から出るとその変数へアクセすることはできなくなる。

もしその変数を利用したい場合は、予めその処理の前に変数を宣言しておき、そこへ代入する必要がある。


第二に、ループを途中で抜ける方法だ。

whileやforを利用している途中で、ある条件が見つかったので繰り返しを終了したいというときが発生する。

その際は(大体の場合はifの並括弧内だが)break;と入力することで、繰り返しを強制的にそこで終了させることができる。

for(int i = 0; i < 1000; i++){
	print(i);
	if(i > 460){
		break;
	}
}

使用言語:Processing


上のコードでは、iが1000になるまで繰り返す処理の中に、条件分岐で460より大きくなったら繰り返しを終了するようにしてある。

上のコードはforで説明したが、同じものをwhileでも利用できる。


最後に、波括弧が不要となる場合についてだ。

if、while/forでは波括弧を使用して処理を記述していたが、これは内部で行う処理をわかりやすくするために使用していた。

というのは少し語弊があるが、ほぼその意味で利用していた。

正確に書くと、波括弧は内部処理が複数の処理である場合に必要となるのだ。

よって、内部処理が1つで終わる場合は波括弧は必要が無い。

int i = 10;
if(i < 2) print("iが2未満です。");

while(i < 11) i++;

for(i = 0; i < 10; i++) i++;

使用言語:Processing


上の処理では波括弧を使用せず、かつ改行せずにコードを書いた。

上の形からわかるように、ifなどとその後に続く処理は一体化して書くことができるのだ。

これにより、若干だが行を短くすることができる。


最初の頃は意識してこの形にする必要はないが、このような書き方をする場合があるので注意してもらいたい。


今回はここまでとする。