対話型AI(人工知能)にアドバイスを受けながら進めるJavaプログラミングの入門連載。今回は、プログラムの実行の流れをコントロールする制御構文について、繰り返し処理とジャンプ構文を学習します。for文とwhile文の違い、どのようなときに繰り返しを使うかを理解しましょう。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
本連載のサンプルコードをGitHubで公開しています。こちらからダウンロードしてみてください。
対話型AIにアドバイスを受けながら進めるJavaプログラミングの入門連載「AIアシスト時代のJavaプログラミング入門」。前回から、制御構文の学習を始めました。そこで最初に「Javaの制御構文ってどんなときに使う?」とGitHub Copilot(以降、Copilot)に投げてみました。ここで改めて注目したいのが、図1の「2.制御構文を使う場面」です。
ここに示された3つの制御構文と、それを使う場面を再掲します。
「条件分岐」は前回で掘り下げましたので、今回は2番目の「繰り返し処理」と3番目の「ジャンプ構文」を掘り下げていきます。
質問「Javaの制御構文ってどんなときに使う?」の回答に戻ると、「1.制御構文の種類と用途」に繰り返し処理についての説明がありました(図2)。
これによると、繰り返し処理には、for文、while文、do-while文の3つがあるようです。説明自体は、「同じ処理を複数回実行する場合に使用します。」などというように非常にシンプルなので、これまで通り新たな質問で掘り下げてみましょう。条件分岐構文に倣って、「繰り返し処理構文について、新しいものも含めて教えて。」と投げてみました(図3)。
今回も、最初に「まとめ」に目を通しておきます。「まとめ」を以下に抜き出してみました。
for文、while文、do-whileがあるというのは前述の通りですが、それらに加えて「拡張for」と「Stream API」いうものがあるということが分かります。そうであれば、まずは基本的な構文を押さえて、理解したところで拡張構文に進み、「Stream API」のように内容の想像も付かないものはまた改めて、という感じに学習を進められそうです。
そこで、図3の「まとめ」にある「for」から「do-while」までを、まずは見ていくことにしましょう。
if文は、「もし○○なら〜」と英単語の意味から動きがイメージしやすかったのですが、forとかwhileはどうでしょうか? なぜ繰り返し処理の構文にこれらの英単語が使われているか聞いてみると、繰り返し処理とfor文/while文の対応がつかめて理解が進むかもしれませんよ!
基本的な繰り返し構文は、質問「繰り返し処理構文について、新しいものも含めて教えて。」への回答において、図4の「1.基本的な繰り返し構文」にあります。
基本的な繰り返し構文として、3つのパターンが示されています。それぞれ、抜き出してみました。
2.と3.は、「do」のありなしの違いだけのようなので、大きく「for文」と「while文」に分かれているように見えますね。
for文は、回数が10回とか、決まった回数だけ何かをしたい、というときに使います。例えば「1から自然数Nの総和を計算して」といったケースです。Nは決まっている、とにかくその回数だけ計算して、というときに使うわけですね。
図4を基に、for文の構文を図にしてみました(図5)。これを見ると、for文は丸カッコの中に「繰り返しの最初に行う処理」「繰り返しを続ける条件」「次の繰り返しに移る前に行う処理」をセミコロン(;)で区切って並べることが分かります。
ここで「コード補完」の機能を使って、上記のケースのコードを示してもらいましょう。今回用に、プロジェクトloopを作成してください。プロジェクトの作り方を忘れてしまった人は、第1回を参照してください。
コード補完してもらうには、あらかじめ、入力したい場所にカーソルを移動させて、macOSでは[Command]+[I]、Windowsでは[Ctrl]+[I]をそれぞれエディタ上で入力します。質問文を入力すると、具体的なコードが提示されるので、[同意する]をクリックして確定させます(図6)。
確定させたら、実行してみましょう。「1から100までの総和は: 5050」と表示されれば成功です(図7)。
ここでは「自然数N」に相当する変数にNを使っているので、Nをいろいろな数値に変えて、実行結果がどう変わるか確認してみましょう。
while文は、繰り返す回数が決まっていない、または決めにくい場合、例えば「自然数Nを2で割った商が0になるまで、商の総和を計算して」といったケースで使います。このようなケースでは、for文の変数Nのように最初から回数を決められません。回数を決めようとすれば計算するしかないので、このようなときにwhile文を使うわけです。
図4を基に、while文の構文も図にしてみました(図8)。while文はfor文と違って至ってシンプルで、「繰り返しを続ける条件」のみを指定すればよいことが分かります。ただし、for文の「繰り返しの最初に行う処理」「次の繰り返しに移る前に行う処理」に相当する処理は、それぞれwhile文の前と、繰り返し処理の最後に記述します。
こちらも、コード補完で上記のようなケースをコードにしてもらいましょう。もう、何をすればよいか分かりますね。
「Nを2で割った商が0になるまでの商の総和は: 97」と表示されれば成功です(図10)。
こちらも、変数Nあるいはquotientをいろいろな数値に変えて、実行結果がどう変わるか確認してみてください(ちなみにquotientとは「商」という意味です)。
ところで、「自然数Nを2で割った商が0になるまで、商の総和を計算して」という質問は日本語としてかなり曖昧なのですが、こういった質問でも的確に回答を導いてくれるのはCopilotの素晴らしい点ですね。
do-while文は、その名前からwhile文に似ていることは想像が付くでしょう。異なるのは、条件判定が後になるので、必ず繰り返しが最低1回は実行される点です。こういったケースには、何が考えられるでしょうか? 例えば「入力した数が0になるまで、その数の総和を計算して」といったケースが考えられるでしょう。
図4を基に、do-while文の構文を、while文と対比する形で図にしてみました(図11)。while文は条件の判定を繰り返しに入る前に行うので(前判定)、条件次第では繰り返し処理が1回も実行されないことがあり得ます。これに対してdo-while文では、条件の判定を次の繰り返しに入る前に行うので(後判定)、条件にかかわらず必ず繰り返しが1回は実行されるという違いがあります。
上記のようなケースでは、何しろ最初の数をとにかく入れてもらわないと先に進まないので、こういったときに後判定のdo-while文を使うわけです。
コード補完で上記のようなケースをコードにしてもらいましょう。ただし、「do-while文で」と付加した方がよさそうです。このことから想像が付くかもしれませんが、do-while文はあまり一般的ではありません。回数未定の繰り返し処理なら、まずはwhile文で記述できるか検討し、どうにも無理ならdo-while文の出番となる、そのように思っておいて構いません。
図13は、その結果です。
ここでは、見慣れない構文が登場しています。「java.util.Scanner(System.in)」などです。簡単に説明すると、標準入力(キーボード)から入力するときの定型的な文となります。繰り返し処理とは直接の関係はないので詳細は省きますが、これも「java.util.Scanner(System.in)の意味を教えて」などと投げてみると、的確な説明が受けられると思うので試してみてください。なお、当該箇所でコンテキストメニューを表示させて、[Copilot]−[説明]を使うと、その場で説明を受けられて便利です(図14)。ここでは実際の説明は省くので、ぜひ試してみてください。
ここまでfor文とwhile文、do-while文を見てきましたが、条件の指定方法は前回の条件分岐と同じです。比較演算子や論理演算子を組み合わせて、単純な条件から複雑な条件まで指定できます。
前回、条件分岐の構造をCopilotに図示させてみるということを試みました。残念ながら期待するような結果にはなりませんでしたが、日々進化するのがAIの世界です。今回も「while文の構造を図示してください。」と投げて図解してもらうことにしました(図15)。
前回同様に、テキストベースで図解してくれました。ただやはり、期待するものとは少し違うようで、まだまだ改善の余地がありそうです。なお、前回は省きましたが、一般的な対話型AI(Microsoft Copilot)でも同様に質問してみました。
画像として生成を試みてくれましたが、残念ながらこちらも期待するものとは違うようです。今後の成長に期待します。
なお図17は、フローチャートでwhile文を表現したものです。
for文もdo-while構文も、最終的にはwhile文に置き換えられそうです。for文で記述した図6のようなコードをwhile文で書き直すとどうなるか聞いてみると、for文で行われていることがより深く理解できるかもしれませんよ!
基本的な繰り返し構文を押さえたところで、次は「拡張for文」です。for文に「拡張」が付いているので、基本的にはfor文なのだなと想像できますね。「繰り返し処理構文について、新しいものも含めて教えて。」の回答の該当箇所「2.拡張for文(for-each文)」を見てみましょう(図18)。今回は取り扱いませんが、「3.Java 8以降の新しい繰り返し構文」も載せておきました。
例を見ると分かりますが、拡張for文には回数を表す変数がありません。また、説明文「配列やコレクションの全要素を順番に処理したいときに便利です。」とあります。「コレクションって何?」という疑問は当然のごとく湧くと思いますが、ここでは「配列」に着目しましょう。どうやら、配列を使うときに便利なfor文のようです。
拡張for文では、配列(およびコレクション)を指定して、その要素を順番に変数に入れて処理する、というのが基本です(図19)。第2回で解説したように、配列の要素数は固定なので、for文の例の変数Nに相当するのは「配列の要素数」ということに自動的に決まります。このように、拡張for文は普通のfor文に置き換えることができますが、簡単に書ける仕組みとして拡張for文が用意されました。
「干支の配列を作って、順番に表示して」をコード補完で試してみましょう(図20)。
干支は12種類あるので、12個の要素を持つ配列が作られますが、それをそのまま拡張for文に渡せば自動で全要素が取り出されて表示されます(図21)。
通常のfor文と対比させるために、「for文で」と付け加えて同様の質問を投げてみました(図22)。
実行結果は変わりませんが、拡張for文が通常のfor文のいろんなところを省いてシンプルに記述できるという仕組みであることが分かると思います。ただし、拡張for文も万能ではなく、例えば変数iに相当するものがないので「何番目」が分からないとか、部分的に配列を処理するといったことには向きません。適材適所で使い分けるとよいでしょう。
拡張for文は、「for-each文」とも呼ぶらしいです。eachというのは構文のどこにも出てきませんが、なぜfor-each文と呼ぶのか聞いてみると、拡張for文の成り立ちや歴史的経緯が分かって興味深いかもしれませんよ!
ここまでで、繰り返し処理の基本構文とされるfor文/while文/do-while文、そして拡張for文を学習しました。今回最後は、「ループ制御文」とされているbreakとcontinueです(図23)。図1では「ジャンプ構文」とされていましたが、役割は同じです。
図23から、ループ制御文の役割を抜粋します。
処理内容は分かるが、使いどころが分からない、そんな感じではないでしょうか。ループを途中で抜けるとは、どんな状況?という具合ですね。構文自体はあえて説明も不要と思うので、これらの文の使いどころを聞いてみましょう(図24、図25)。
説明自体は大きく変わりませんが、例も示されたことで、使いどころがイメージしやすくなりました。いずれも、if文などの条件分岐と組み合わせて、特定の条件で「ループから抜ける」「ループの最初に戻す」構文のようです。ジャンプ構文の名を借りれば、「ループの直後にジャンプする」「ループの先頭にジャンプする」というイメージです。
break文は、この例では拡張for文の中で使い、目的を達成したらループを終了させることができます。拡張for文は、配列などの要素を全て処理するまで終わらないので、この例のように目的の要素が見つかったら終了するという術を持ちませんから、break文と組み合わせることで不要な繰り返しを実行せずに済みます。
continue文は、この例ではfor文の中で使い、特定の条件ではループ内の処理を実行しないときに使えます。例では示されませんでしたが、ユーザーからの入力が条件を満たすまで何回も入力させる、そんな使い方もできそうです。
第3回でswitch文を学習しましたが、そこではbreak文が使われていました。そこでは、このように書かなければならないものとして紹介しましたが、switch文をその場所で抜けるというように理解すれば、break文をなぜそこに書かなければならないか理解できるでしょう。
break文もcontinue文も、if文と組み合わせて処理の流れを変えるための構文です。ということは、break文/continue文を使わずに同じロジックを記述できるとも考えられます。図23などの例のコードを書き直してもらうと、break文/continue文の働きを深く理解できるかもしれませんよ!
今回は、条件分岐と並んでプログラムの流れをコントロールする制御構文である、繰り返し(for文、while文など)を、ループ制御文と併せてCopilotに聞きながら学習しました。
次回は、Javaにおけるオブジェクト指向の基本である、クラスについて学習します。
WINGSプロジェクト 山内直
WINGSプロジェクト所属のテクニカルライター。出版社秀和システムを経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。
・たまデジ。 | たまプラーザで生活、仕事する。(https://naosan.jp/)
WINGSプロジェクト
有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティー(代表山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手掛ける。2021年10月時点での登録メンバーは55人で、現在も執筆メンバーを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。
・サーバーサイド技術の学び舎 - WINGS(https://wings.msn.to/)
・RSS(https://wings.msn.to/contents/rss.php)
・X: @WingsPro_info(https://x.com/WingsPro_info)
・Facebook(https://www.facebook.com/WINGSProject)
Copyright © ITmedia, Inc. All Rights Reserved.