皆さんこんにちは、TaroTechです。
今回はJavaにおける繰り返し処理の制御文である「while文とfor文」について解説していきます。
Javaのプログラミングをしていく際に繰り返し処理はよく使用します。
時には同じような処理を10回、100回と繰り返すこともあります。
そんな処理を繰り返すときに、ソースコードをよりシンプルに分かりやすくしてくれるのが今回紹介する繰り返し文になります。
この記事ではその繰り返し処理を表現する際に使用するwhile文・for文・do while文についてサンプルコードとフローチャートを用いてわかりやすく解説していきます。
1.while文の構文とサンプルコード
while文はユーザーが設定した条件が真である限り処理を繰り返す文法になります。
構文
繰り返しパラメーターの初期化
while(条件式){
繰り返す処理
}
キーワードwhileの後の()の中に繰り返しの継続条件式を指定します。
()の中の条件式の値はboolean型(true or false)になる必要があるため、条件式には関係演算子を用いて式を記述します。
()直後の{}ブロックの中には条件式が真(true)の場合の繰り返し処理を記述します。
構文の流れとしては、まず()内の条件式の真偽判定を行い(前判定)、真である場合は{}内の処理を実行し、その後も条件判定が偽になるまでは判定と処理の実行を繰り返していきます。
サンプルコード1
public class Example1 {
public static void main(String[] args) {
// 繰り返し用パラメーターの初期化
int i = 0;
while (i < 5) {
System.out.println("気合いだ!");
i++;
}
}
}
まずwhileブロックの外側で繰り返し用のパラメーターを初期化します。今回はiというint型の変数を0で初期化しています。
次に、while直後の()内に継続条件を記述します。上記の例では「i < 5」としているので、iが5より小さいとき、つまりi = 4まで繰り返すということになります。
{}内の処理としては、「気合いだ!」と表示させた後にiをインクリメント(1増やす)する処理を記述します。
よって上記の例だと、iが0から4まで「気合いだ!」を表示させるので、5回 「気合いだ!」 が表示されるという処理になります。
2.for文の構文とサンプルコード
for文はユーザーがパラメーターを設定することで繰り返し処理の実行回数を指定できる構文です。
構文
for(式1 ; 式2 ; 式3){
繰り返す処理
}
式1:繰り返しの前に1度だけ実行する処理
式2:繰り返しの継続条件判定式
式3:繰り返し処理が1周するたびに実行される処理
キーワードforの直後の()中を「セミコロン(;)」で区切って、3つの式を記述します。
式1には繰り返し処理を実行する前に1度だけ実行する処理を記述します。一般的には繰り返し処理の開始条件(初期条件)を記述します。
式2には繰り返し処理の継続条件を記述します。while文の場合と同様に、条件式の値はboolean型(true or false)になる必要があるため、条件式には関係演算子を用いて式を記述します。
式3には{}内の処理が1周するたびに実行される処理を記述します。
多くの場合、算術演算子等を用いて初期設定したパラメーターの増減を行います。
()直後の{}ブロック内にはwhile文の時と同様に繰り返したい処理を記述します。
for文の処理の流れは、
①条件の初期化→②継続条件判定→③(真なら){}の処理を実行→④式3の実行→以降、条件判定が偽になるまで②~④を繰り返す
となります。
サンプルコード1
public class Example2 {
public static void main(String[] args) {
int total = 0;
for (int i = 1; i <= 10; i++) {
total += i;
}
System.out.println("1から10までの合計は" + total);
}
}
サンプルコード1では1から10の合計を計算する処理をfor文で表現しています。
まず、for直後の()内の式1で繰り返しパラメーターであるiをi = 1で初期化しています。
次に、式2で継続条件判定を行い、真だった場合は{}内に移ってtotalという変数にiを加算する処理を行います。
{}内の処理が実行されたら()内に戻って式3の処理が実行されます。今回はi++なのでiが1増えます。
次に、また式2に戻って条件判定を行い、偽になるまで処理と判定を繰り返します。
サンプルコード2
public class Example3 {
public static void main(String[] args) {
int total = 0;
for (int i = 1; i <= 10; i--) {
total += i;
}
System.out.println(total);
}
}
サンプルコード2はサンプルコード1のfor()内の式3をi++からi--(デクリメント)に変えただけになります。
このコードの注目ポイントは継続条件が無限ループになっている点です。
上記の例では初期条件がi = 1、継続条件はi <=10で{}内の処理が繰り返されるたびにiから1を引くという処理になっています。
この記述だと{}内の処理が行われるたびにiの数が小さくなっていくので、いつまでたっても継続条件は真のままになってしまい、いわゆる無限ループになってしまいます。
今回実行結果が吐き出されているのはint型の下限値にたどり着いてしまい、これ以上コンピュータ上で計算できないから結果が出ているだけなのです。
このように条件設定を誤ると無限ループになってしまうので、条件判定の設定は注意して行いましょう。
3.do while文の構文とサンプルコード
do while文はwhile文と同様に条件が真である限り処理を繰り返します。
繰り返しパラメーターの初期化
do{
繰り返す処理
}while(条件式);
キーワードdoの直後に{}ブロックを記述し、ブロック内には判定条件が真の場合の処理を記述します。
}の後にwhileキーワードとその直後に()を記述し、()の中には関係演算子を用いた条件式を記述します。さらに()の直後には「セミコロン(;)」も必要なので注意しましょう。
処理の流れについては、while文が条件判定をしてから{}の処理を実行していた(前判定)のに対して、do while文は{}内の処理を実行してから条件判定を行う後判定処理になります。
サンプルコード
public class Example3 {
public static void main(String[] args) {
//繰り返し用パラメーターの初期化
int i = 0;
do {
System.out.println("へえ~");
i++;
}while(i < 5);
}
}
まずdo whileブロックの外側で繰り返し用パラメーターを初期化します。
次にdo直後の{}ブロック内の処理を実行し、そのあとのwhile()内の条件式で継続判定を行います。
上記の例だと初期条件がi = 0で継続条件がi < 5なので、「へえ~」という文字列が5回表示されます。
4.繰り返し文のネスト(重ね合わせ)
繰り返し文のネストとは、繰り返し文の{}ブロックの中にさらに繰り返し文を重ねることを指します。
複数のパラメーターを使用してより複雑な処理を簡単に記述することができますが、重ねすぎるとコードの読みやすさ(可読性)が下がるので注意しましょう。
サンプルコード
public class Example4 {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
// for文のネスト
for (int j = 1; j <= 9; j++) {
System.out.print(i * j);
//半角スペース
System.out.print(" ");
}
// 改行
System.out.println();
}
}
}
サンプルコードでは1から9の段までの掛け算の九九を表現しています。
まずはパラメーターiで記述したfor文が処理され、{}内に入ります。
するとさらにパラメータjで記述した内側のfor文の処理が行われます。
処理の流れを説明すると、まずi = 1の時に内側のfor文のjが1~9までの間、「i * j」という処理と「半角スペースの空白を開ける」処理が繰り返されます。
j = 10になったタイミングで内側のfor{}から抜けて一度だけ改行する処理が行われます。
そうすると次にiが+1されてi = 2になったら再び内側のfor{}が処理されるので、jが j = 1で初期化されj = 9まで同様の処理が行われます。
図で説明するとこんな感じ
i = 1 → j = 1からj = 9まで 「i*j」と「空白スペースの挿入」を実行
1回だけ改行
i = 2 → j = 1からj = 9まで 「i*j」と「空白スペースの挿入」を実行
1回だけ改行
・
・
i = 9 → j = 1からj = 9まで 「i*j」と「空白スペースの挿入」を実行
1回だけ改行
5.繰り返し文の制御(breakとcontinue)
本来、繰り返し文は条件判定式の結果が偽になるまで処理を繰り返しますが、breakキーワードとcontinueキーワードを用いると継続条件判定式の結果に関係なく途中でループを終わらせたり飛ばしたりすることができます。
breakとcontinueは挙動が少し異なるので、サンプルコードを用いて違いを見てみましょう。
5-1.break文
break文はfor文の継続条件判定の結果に関係なくループを強制終了させることができます。
なお、強制終了の対象はbreakが書かれたfor{}ブロックになります。また、break文は通常if文などの条件分岐と一緒に用いられます。
サンプルコード
public class Example5 {
public static void main(String[] args) {
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <=9; j++) {
if(i == 4 || j == 6) {
break;
}
System.out.print(i * j);
//半角スペース
System.out.print(" ");
}
//改行
System.out.println();
}
}
}
上記の例も掛け算の九九を表現したコードになります。
まず、i = 1のときに内側のループに入ります。
j = 1から順に内側のfor{}内の処理(図の青枠)が実行されます。上記の場合だとi = 4または j = 6の時にbreakが実行され内側のループを抜けるため、1周目なら i =1、j = 5までしか内側のループ内の処理は行われません。
そのまま処理を続けていくと、i = 4になったときは j =1の1回目の内側のループの時点でbreakされるため、4の段は一度も実行されることなく次の段に進みます。
このように最後まで処理を行っていくと、結果的に4の段を除いた格段の「○×5」までの計算結果のみ表示されるという挙動になります。
5-2.continue文
continue文はループ内の処理をスキップし次の回に進ませる制御を行う文になります。
なお、スキップの対象はcontinueが書かれたfor{}ブロックになります。また、continue文は通常if文などの条件分岐と一緒に用いられます。
サンプルコード
public class Example6 {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
if (i == 4 || j == 6) {
continue;
}
System.out.print(i * j);
// 半角スペース
System.out.print(" ");
}
// 改行
System.out.println();
}
}
}
上記の例も掛け算の九九を表現したコードになります。
まず、i = 1のときのほかの例と同様に内側のループに入って、j = 1から順番に処理が実行されていきます。
j = 6になったタイミングでcontinueが走り、そのまま{}内の処理をスキップしてj++が実行されます。また j = 7になったらu内側の{}の計算処理が行われ後続に続いていきます。
そのまま処理を続けていき、i = 4になったときに内側のループに入ると、j= 1の時点から処理がスキップされj++が実行されます。このままi = 4の時は j = 9になるまでj++のみ実行されるため、結果的に4の段の計算結果は1つも表示されません。
このように処理を続けていくと、全体の結果としては、「○×6」と「4×△」以外の計算結果が表示されるという挙動になります。
確認問題
Q.繰り返し文と制御キーワードを用いて以下のように表示させよ。
public class Question1 {
public static void main(String[] args) {
// 処理を記述
}
}
tips
空白スペース:System.out.print(” “);
*を表示(改行なし):System.out.print(“*”);
改行:System.out.println();
確認問題の解答
public class Question1 {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == j) {
System.out.print(" ");
continue;
}
System.out.print("*");
}
System.out.println();
}
}
}
ポイントは赤字で示した、if()内の条件指定と{}内の処理になります。
i == jのときは空白スペースを表示してcontinueすることで実行結果のように斜めだけ空白の*正方形が出来上がります。
ちなみに、continueを使わない場合は以下のコードが考えられます。
public class Example7 {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == j) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
System.out.println();
}
}
}
このように様々な文法を組み合わせることで複数の処理を表現することができるので、ぜひ文法を覚えて組み合わせて使えるようになりましょう。
コメント