こんにちは､ そしてようこそ｡ この講義では､ whileループとdo whileループについてお話したいと思います｡
これまでforループについて説明してきましたが､ forループは基本的にコードの繰り返しを可能にします｡
cには他にもwhileやdo whileという構文があり､ 構文が違うだけで同じようなことができます｡
つまり､ whileループは一連のステートメントを繰り返す仕組みで､
指定した論理式の評価がtrueである限り､ 実行を継続させることができる｡
だから､ ここでも同じようなことが言える｡ if文が特定のコードを実行するように､
while文はブール評価に基づいて特定のコードを何度も実行します｡
forループでできることはすべてwhileループでもできます｡
構文が違うだけです｡
では､ whileループはどのようなものかというと､ 次のようなものです｡
非常に高いレベルで､ 疑似コードを見てみると､ この条件がtrueである間は､
これをやり続ける｡
そこで､ もっと世界の世界の例と関連づけると｡
基本的に､ お腹が空いている間は､ サンドイッチを食べる､ みたいな感じです｡
つまり､ コードを繰り返すということですね｡ お腹が空いている間は､ 何個もサンドイッチを食べ続けることになります｡
whileループの一般的な構文は以下の通りです｡
そして､ これは本文中の1つのステートメントの構文を示しているので､
ブラケットや中括弧を用意する必要はありません｡
私は､ 中括弧とブラケットを同じ用語で使うことが多いですね｡
では､ 1つのステートメントと複数のステートメントを持つ場合の構文はどのようになるのでしょうか｡
複数の文を記述する場合は括弧が必要ですが､ 単一の文を記述する場合は括弧は不要です｡
持てないのか､ 持たなくていいのか｡
式は､ forループやif文と同じように括弧の中に入れる｡
ここでの式は､
forループと異なり､ 終了条件が1つである｡
表現なんです｡ ループ制御変数を初期化しない｡
括弧の間にあるループ制御変数を変更しない｡
式だけ､ 終了条件だけなんです｡
whileループの継続条件は､ 開始時にテストされます｡
これがループのトップなんですね｡
つまり､ これはプレテストループということです｡ つまり､ 0回実行されることもあれば､
ボディ内で複数回実行されることもあるということです｡
そしてまた､ これはdo whileループが少し異なることを行っているので､ 関連することになります｡
もし､ 式の最初がfalseなら､ 本文のループ文はどれも実行されない｡
だから､ トップ・テストになったんですね｡
だから､ 最初の質問で「お腹が空いてない」と答えたら､ サンドイッチは絶対に食べないようにしましょう｡
あなたはコーヒーや次のコードの行にまっすぐ移動するつもりです｡
ループの本体に入らない｡
ループの開始条件がtrueの場合､ ループを終了させるには､
ループ本体にこれを変更する機構が必要である｡
そうでないと､ 無限ループに陥ってしまいます｡
つまり､ ループ制御変数を1つの文で変更するforループと､ 本文で変更することを除けばwhileループは同じことなのです｡
whileループは､ どこかでループ制御変数を初期化し､
コード本体内部を修正することになります｡
さっきも言ったように､ whileループはforループができることは全部できるんだけど､ 構文が違うだけなんだ｡
そしてまた､ forループはmore is shortです｡ whileループでは3つのことを別々の行で行わなければならないのに対して､
1つの行ですべてを行うことができます｡
つまり､ この例では､ int
countは0に等しいということです｡ ループ制御変数です｡ これはwhileループ文の外側です｡
for文の場合は､ 最初のセミコロンの前と同様に､ forループの中に入ります｡
そこで､ ループ制御変数を初期化する｡
そして､ whileキーワードと､ 括弧の中にブール式を記述しています｡
これは､ forループと同じで､ 2つ目のセミコロンの直前の文になります｡
これがtrueかfalseかをチェックするものなんですね｡ そして､ それがtrueかfalseなら､ ループの本体に入るのです｡
countが5以下なら､ カウントをプリントアウトすることになる｡
その次の行はとても重要です｡ プラス・プラス・カウントは､
ループ制御変数を変更しているからです｡
このプラス・プラス・カウントをしないと､ ループを抜けることができないんだ｡
カウントが常に1であれば､
無限ループになります｡
だから､ そのプラスアルファのカウントがとても重要なんです｡
plus plus count remember は､ インクリメント演算子です｡
カウントとカウントプラス1が等しいというだけです｡
このループは5回実行されます｡
カウントが1､ カウントが2､ カウントが3､
カウントが4､ カウントが5で実行されるんだ｡
countが6になったら､ ループから飛び出して､ それ以上ボディ内のステートメントを終了させないようにします｡
ここでも､ forループで考えるべきでしょう｡
ループ制御変数だけで､ ループ制御変数の修正は実際のループの宣言にはない｡
forループのように1行にまとまっているわけではありません｡
ここでも､ ループを終了するようにロジックを制御する例を紹介します｡
最初の例では､ カウンタ制御のループを示しました｡
常に同じ回数､ つまり5回実行されることになるのです｡
次の例では､ ループが100回実行される場合と0回実行される場合がある例です｡
numがマイナス1でないという条件をwhileキーで評価していますが､
numはユーザーが入力したものなので､ すべてユーザーが入力したものに依存します｡
つまり､ このループは0回実行されるかもしれないし､ 100回実行されるかもしれない｡
すべては､ キーボードからの入力に依存する｡
そして､ これをセンチネル・コントロール・ループと呼びます｡ カウンターコントロールされていないのです｡
変わる可能性のあるロジックと変数に基づくものです｡
つまり､ numがマイナス1でない間は､ キーボードで入力した値がnumに格納されます｡
もし､ ユーザーがキーボードで負の1を入力することがなければ､ このループは決して終了することはない｡
同じような構文で､ "while "を使っているわけです｡
ここでのループ制御変数はnumです｡ 一番上の0を初期化し､ ユーザーがキーボードで入力した内容に基づいてループに入るかどうか､
モディファイして読み込んでいるのです｡
そして､ whileキーワードの括弧の中で､ 実際にマイナス1であるかどうかをチェックしているのです｡
そして､ whileループの本体に括弧を付けます｡ 単一のステートメントなので括弧は必要ないのですが､
私は括弧を付けるのが好きです｡
そして､ 次の入力も読み込んで､ numに格納する｡
その次の入力に負の1を入力すると､ ループから飛び出す｡
そうでない場合は､ 実行を継続し､ 情報の入力を求めます｡
do whileループは､ whileループのforループとは少し異なり､
テスト後のループとみなされるからです｡
つまり､ whileループでは､ 条件が成立している間､ 本体が実行される｡
本体が無条件に初回実行されるdo whileループでは､
テストが一番下にあるため､ 必ず一度はループを実行することになります｡
少なくとも1回､ それ以上かもしれませんが､
常に1回､ 決して0回ではありません｡
出口をテストする条件が一番下にあるからです｡
これをポストテスト・ループといいます｡ 出口制御ループとも呼ばれる｡
つまり､ 少なくとも1回はループを入力させたい場合は､ do a whileループを使うことになります｡
通常､ do whileループを使わなくても､
forループで同じことができるので､ ループの外にコードを置くだけでよいのです｡
というわけで､ do whileループはあまり必要ないのですが､ 場合によっては使いたいこともあります｡
初回実行後は､ 条件が真の間のみボディが実行される｡
つまり､
ループの最初の繰り返しの後は､ 通常のループと同じように動作することになります｡ 条件が偽の場合は飛び出します｡
というわけで､ こんな感じです｡ doが一番上にあり､ 条件のテストはwhileキーワードで一番下にある｡
つまり､ doは新しいキーワードで､
本文中に複数のステートメントがあるかどうかによって､ 括弧をつけるかつけないかを決めることになります｡
ボディに1つの文しかない場合は､ ブラケットをつけることはないでしょう｡ 上部でやって､ ループの下部でwhileをすればいいんです｡
そして､ whileの中の括弧の中には､ チェックする条件となるブール値の評価があります｡
しかし､
繰り返しになるが､ この条件は一番下にあるため､ 常に少なくとも1回は文が実行されることが保証されている｡
そして､ 左の例は1つのステートメントで､ 右の例は複数のステートメントです｡
つまり､ 括弧と中括弧があるわけです｡
また､ この2つ目の例では､ パスワードの入力を促し､ ユーザーの入力を読み､ 入力がパスワードと等しくない場合に､
パスワードの入力を促すようなことができる､ と言っていますね｡
しかし､ 少なくとも一度は必ずそのパスワードを要求されます｡
そこで､ もうひとつ､ whileループの例を挙げてみましょう｡
ここでの1番上の例は､ ループが1回だけ実行される場合と何回も実行される場合があるが､
決して0にはならない例である｡
すべてはユーザーが入力する内容次第です｡ 必ず一度は実行されるのですが､ これはキーボードからの入力を読み取っているのです｡
scanf関数を見ます｡
そして､ ユーザーが20を入力しない限り､ このループを実行し続けることになるのです｡
whileループはカウンタ制御ループにもなり､ ある回数だけ実行されることを意味します｡
この例では4回実行することになります｡
int数が4に等しいことがわかります｡ そして､ 一番上にdoがあり､ bodyの中に複数のステートメントがあるため､
ブラケットがあるのです｡
そして､ 本体内部のループ制御変数､ ナンバープラスプラスをインクリメントしています｡
そして､ チェックする条件は､ やはり一番下にあります｡ これを4回実行するわけですね｡
そして､ while キーワードは右中括弧と同じ行にある必要はないことにお気づきでしょう｡
一般的にはそうですが､ そうである必要はないのです｡
そして､ 下部のwhileキーワードもセミコロンで終わっていることにも注目してほしい｡
これまで､ forループ､ whileループ､ do whileループについて学んできました｡
どのようなループを使えばいいのでしょうか？
さて､ まずどのようなループを使うかですが､ まずプレテストにするかポストテストにするか？
最低限実行させたいのか､
最低限実行させたくないのか？ 少なくとも1回は実行させたいのであれば､
do whileを使うことになります｡ それが条件でないなら､
forやwhile､ do whileを使えばいい｡
だから､ どのループを使うかを決めるときは､ ほとんどの場合､ 必ずテスト前のループを使うことになるんだ｡
do whileループには近づかない方がいい｡
ほとんどの場合､ より良い選択肢であることに変わりはありません｡ より読みやすくなりました｡
実際にループする前に見る方がよっぽどいい｡
ただ､ ループし始めないように､ その条件を一番最初に確認したほうがいい｡
読みやすさを考えると､ ループがテストのところにあれば､ より直感的に理解できます｡
そのため､ ループのチェックを最初に行い､ forやwhileを使用するようにします｡
また､ 多くの場合､ 最初にテストが満たされないとループが完全にスキップされることが重要です｡
繰り返しになりますが､ そうであるからこそ､ テストは一番上にあるべきなのです｡ 常に一度は実行しているわけではないはずです｡
ほとんどの場合､ あなたは常に実行したいと思わないかもしれません｡
だから､ しばらくはaを使ったほうがいい｡
さて､ しばらくはどれを使ったらいいのだろうということになる｡
本当に個人の好みの問題です｡ この講義の冒頭で述べたように､
一時的にできることはすべて､ 一時的にできるのですから､ 問題ないでしょう｡
ループの制御や初期化､ 終了条件などをすべて1行で済ませることができるので､
forループの方が好きな人は､ forループの方が少し早く処理できる場合があります｡
でも､ 本当に自分次第なんです｡
通常､ 私が行うのは､ カウンター制御のループにforループを使用することです｡
でも､ もう一度､ 同じように使ってみてください｡ 実際にforループを使ってwhileのようにしたい場合は､
1つ目と3つ目の式がないだけで､ 1つ目の式があるだけです｡
つまり､ forセミコロンテストのセミコロンはwhileテストと同じなのです｡
つまり､ これはwhileのforでも同じことができることを示しただけで､ 構文を少し変えただけなのです｡
実際にwhileループを使いたいが､ forループのように動作させたい場合は､
初期化の前にupdate文を入れて､ 本文にupdate文を入れておくことになる｡
通常､ このような処理はwhileループで行います｡
しかし､ これではforループに相当する｡ 初期化は､ 制御変数であるループ制御変数のループ外です｡
括弧の中にtestの条件があり､ whileループの本体でそのループ制御変数を更新しているのです｡
そしてそれは､ forループの初期化テストの更新､ そして本体と同じです｡
違いはないんです｡
繰り返しになりますが､ 私はforループをカウンタ制御のループに少し使うことがあります｡
でも､ その日の気分でforとwhileの両方を使い分けています｡
ですから､ 一行で変数の初期化と更新を行いたい場合は､
forループの方が少し適切かもしれません｡
それ以外の条件の場合は､ whileループの方が良い｡
繰り返しになりますが､ カウンタ制御のループはfor､ センチネル制御のループは多分whileループです｡
そして､ センチネル制御のループと同じことを繰り返しているwhileループや､
カウンターを制御しているforループの例です｡
ループはユーザーが入力した内容に応じて何度も実行することができますが､
forループはカウンタ制御です｡
つまり､ これはdo whileのwhileにあたる｡ これがクリアできるといいのですが｡
コードを繰り返すことが多いので､ これらのループに慣れ親しんでください｡
ループの入れ子や､ breakやcontinueを使ったループの抜け方など､
少し変わった話もします｡
ありがとうございます｡