0
0

More than 1 year has passed since last update.

JAVA 基本文法[4] - 制御構文(条件構文/繰り返し構文)

Last updated at Posted at 2023-03-05

前提知識:プログラムの流れ
代表的な「制御構造(制御フロー)」
・順次: 上から順に文を実行する
・分岐: 条件によって違う文を実行する
・繰り返し: 条件が満たされるまで同じ文を繰り返す

「制御構文」の構成要素

※「制御構文」:if/while文のような制御構造を表す文のこと。
「条件式」と「ブロック」から成り立つ。

●ブロックの書き方
ブロックとは、複数の文をひとまとまりとして扱う為のもの。

・ルール①:スコープの範囲を抜けると、その変数は消滅する。
「ブロック内で宣言した変数は、そのブロックが終わると同時に消滅する」ため、ブロック内で宣言した変数はブロック外では利用できない。
このような「変数が利用可能な場所の範囲」のことを「スコープ」という。

上記のようなとき、while文の後に変数bを使用すると「シンボルが見つけられません。 シンボル:変数b」というコンパイルエラーになる。

・ルール②:内容が1文しかない場合、波カッコの省略が可能
※ただ実際の開発現場では、プログラミングのミス防止の為、省略は推奨されない。

Main.java
//例
public class Main {
  public static void main(String[] args) {
    boolean tenki = true;    // (ここでtrueかfalseを代入)
    if (tenki == true) { //内容が2行なので波括弧は省略不可
      System.out.println("洗濯をします");
      System.out.println("散歩にいきます");
    } else //1行しかないので波括弧は省略OK
      System.out.println("DVDを見ます");
  }
}

●「条件式」の書き方
「条件式」とは制御構文で利用される式。条件式の中身が評価されて分岐や繰り返しが処理される。

・「関係演算子」を用いる

関係演算子 意味
== 左辺と右辺が等しい initial == '辰'
変数initialに入っている文字が「辰」なら
!= 左辺と右辺が異なる sw != false
変数swがfalseでなかったら
> 左辺が右辺より大きい
< 左辺が右辺より小さい deg - 2.5 < 0
変数degから2.5を引いたものが0未満なら
>= 左辺が右辺より大きいか等しい
<= 左辺が右辺より小さいか等しい

注意:「等しい」を表現する関係演算子は、イコールを2つ並べた「==」。=は代入演算子となり異なる動作になる為注意しよう。また、この際にコンパルエラーにもならないので厄介である。

関係演算子にも「評価されて化ける」という特性を持つ。関係が成立するなら「true(真)」をそうでなければ「false(偽)」に化ける。

「制御構文の条件式は評価結果が、trueまたはfalseになる式でなければならない」

・文字列の比較の場合、==ではなく「equals」を使う。

文字列の比較
文字列型の変数.equals(比較相手の文字列)
※「比較相手の文字列」は、文字列のリテラルや変数を指定可。
※「文字列型の変数」と「比較相手の文字列」が等しければ、この式の全体がtrueに化ける。

Main.java
//例
if (str.equals("夕日")) {...

・「論理演算子」を用いた複雑な条件式

論理演算子 意味
&& かつ(両方の条件が満たされていた場合true。そうでなければfalse。)
|| または(どちらか片方の条件さえ満たされればtrue。どちらも満たしていない場合false。)
Main.java
//例1:もしageが18歳以上で、かつmonthが5月なら
if (age >= 18 && month == 5) {...

//例2:もしnameが髙橋、または高梁なら
if (name.equals("髙橋") || name.equals("高梁")) {...

「&&」と「||」の組み合わせ技も可能!

Main.java
//例「『powerが100未満、かつpoisonがfalse』または『powerが100以上、かつpoisonがtrue』のときブロックの中身が実行される」
if ((power < 100 && poison == false) || (power >= 100 && poison == true)) {...

・「否定演算子」の「!」を用いた条件式
「もし〜でないならば」のような否定形の条件式を作りたい場合、条件式の前に「!」をつける。
『「もし〜でないならば」、「true」という評価になる』

Main.java
// 例 「ageが10に等しくない(10以外)なら「true」。(10で等しいとき、falseになる)」
if (!(age == 10)) {...

分岐構文(4種類)

※分岐:条件によって違う文を実行する。

●「if-else構文(基本形)」
●「ifのみの構文」
●「if-else if-else構文」
●「switch構文」

(if構文POINT)
・if構文の3つの違いは、条件式の評価結果がfalseになったときの流れにある。
・ifの後ろのカッコ内には「晴れているか?」などの条件分岐をかく。
・条件分岐が成立していたら、()の直後にあるブロック({}で囲まれた部分)の中身だけが実行される

●「if-else構文(基本形)」
条件分岐が成立していなければ、elseの後ろにあるブロック({}で囲まれた部分)の中身だけが実行される。
falseが1つのみ。

Main.java
//例)
public class Main {
  public static void main(String[] args) {
    boolean tenki = true;
    if (tenki == true) {
      System.out.println("洗濯をします");
    } else {
      System.out.println("DVDを見ます");
    }
  }
}
/*実行結果
//3行目のboolean tenki = true;のように「true」を代入したときは…
洗濯をします
//3行目で「false」を代入したときは…
DVDを見ます
*/

●「ifのみの構文」
もし、「条件が満たされなかった場合(falseのとき)は何もしない」といったときに「ifのみの構文」を使う。
else文を省略する。

Main.java
//例
if (age >= 20) {
  canCigarettes = true;
}

●「if-else if-else構文」
もし、「条件が満たされなかった場合、別の条件で評価したい」ときに「if-else if-else構文」を使う。
※falseのとき、さらに別の条件で分岐したいとき。
「1つのif文で3つ以上のルートに分岐できる」特徴を持つ。
※最後のelse「最終ブロック」の中身が空の場合は、elseごと省略可。

Main.java
//例
if (weight >= 60) {
  size = 'L';
} else if (weight >= 50) {
  size = 'M';
} else if (weight >= 40) {
  size = 'S';
} else {
  size = '?';
}

●「switch構文」
「switch構文」は、「if-else if-else構文」をよりスッキリさせた文である。

switchの直後に書くのは、条件式(変数名==1など)ではなく、「変数名」を記述。

「caseラベル(〜の場合)」の横には、「値」を書き、その後ろに「コロン(:)」を書く。

基本的に、case以降の処理の末尾には「break」文を記述する。※あえて書かないテクニックもある。
「break」を書くことで処理を中断してswitch文を抜けることが出来る。
「switch文は条件に一致するcaseラベルまで処理がジャンプさせる命令」であるため、breakを書き忘れると、条件に一致したcaseラベルの処理後のcaseも順次進んでしまう。

default:は、条件に合致しない時の処理を記述、処理が不要な場合は省略可能。

・switch構文に書き換えることが出来る3条件 (全てを満たすこと)
①全ての条件式が「変数==値」や「変数==変数」のように左辺と右辺が「一致するか比較する式」になっている。その他の「>」「<」「!=」が使われていないこと。
②比較する値が「整数(int/byte/short型)」、「文字列(String型)」、「文字(char型)」のいずれかであること。小数や真偽値ではないこと。
③同じ変数に対して繰り返し比較を行なっているとき。

Main.java
//例
switch (fortune) {
  case 1:
    System.out.println("大吉");
    break;
  case 2:
    System.out.println("中吉");
    break;
  case 3:
    System.out.println("吉");
    break;
  default:
    System.out.println("凶");
}
Main.java
//あえてbreak文を書かないテクニック…
public class Main {
  public static void main(String[] args) {
    System.out.println("あなたの運勢を占います");
    int fortune = new java.util.Random().nextInt(5) + 1;
    switch (fortune) { //1〜5の乱数発生
     case 1: //fortuneが1か2なら
     case 2: //fortuneが1か2なら
       System.out.println("いいね!");
       break;
     case 3: //fortuneが3なら
       System.out.println("普通です");
       break;
     case 4: //fortuneが4か5なら
     case 5: //fortuneが4か5なら
       System.out.println("うーん…");
    }
  }
}

繰り返し構文(3種類)

繰り返し構文:条件が満たされるまで同じ文を繰り返す。「繰り返しを続ける条件が成立している限り、何度でも直後のブロック{}の中身だけが繰り返し実行される。

※trueを代入して実行すると無限ループになる…
JDKを利用している場合ctrl+C、統合開発環境を利用している場合停止ボタンを押して、強制終了すること。

●while構文(基本形)
●do-while構文
●for文

((while構文))
2つの違いは、「ループの最低回数」。
whileの後ろの()は、繰り返しを続ける条件を書く。
「ある条件が成立するまで繰り返す」

●while構文(基本形)
「ブロックを実行する前に条件式を評価」する。これを「前置判定」という。
つまり、「初めから条件式の判定結果がfalseの場合」は「一度もブロックが実行されない。」

Main.java
//例
while (temp > 25) {
  temp--;
  System.out.println("温度を1度下げました");
}

●do-while構文
「ブロックを実行した後に条件式を評価」する。これを「後置判定」という。
そのため、「最低1回はブロックを実行する」。

Main.java
//例
do {
  temp--;
  System.out.println("温度を1度下げました");
} while (temp > 25);

●for文
「回数指定の繰り返し」。
※while/do-while構文でも記述できないことは無いが、for文の方がシンプルに記述することができる。
ループ変数を用いて「〜回繰り返す」という場面に使用する。
ブロックを実行する前に条件式を評価する「前置判定」である。
break文を実行すると繰り返し自体を中断し、continue文を実行すると繰り返しの次の周回へ進むことができる。

Main.java
//例 こんにちはを10回表示されるプログラム
public class Main {
  public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
      System.out.println("こんにちは");
    }
  }
}
/*実行結果
こんにちは
・
・
(こんにちはが10回表示される)
*/

for文の基本形:◯回繰り返す

繰り返す回数10の部分の数値を変えるだけで、100回繰り返したい、50回繰り返したいなど他の数値で対応出来る。

・for文の構成要素3つ

①「初期化処理」
forによる繰り返しが始まるにあたり「最初に1回だけ実行される文」
通常、「何周目のループかを記録しておく変数」を定義する。この変数を「ループ変数」という。
★「ループ変数」を扱う時の注意3つ
(1)ループ変数の名前は自由。但しfor文より前で宣言されている変数名は使えない。一般的に1文字の短い変数名を用いられることが多い。
(2)ブロック内で利用可能。ループ変数も通常の変数の一種で、「ブロック内での計算や表示に使える」。

Main.java
//例 「for文のループ変数iの内容を表示する」
public class Main {
  public static void main(String[] args) {
    for (int i = 0; i < 3; i++) {
      System.out.print("現在" + (i + 1) + "周目→");
    }
  }
}
/*実行結果
現在1周目→現在2周目→現在3周目→
*/

(3)ブロック外では利用不可。for文のブロック内でのみ有効。for文を抜けるとループ変数は消失する!

②「繰り返し条件」
ブロック内容を実行する前に評価され、このループを継続するか否かを判定する条件式。
trueの間は、{以降のブロックが繰り返し実行される。

③「繰り返し時処理」
for文内のブロックを最後まで処理して、「}まで到達した直後に自動的に実行される文」である。
一般的に「i++」のようにループ変数の値を1だけ増やす文を書くことが多い。

for文の応用形

・ループ変数を1からスタートする。
for (int i = 1; i < 10; i++) {...}

・ループ変数を2ずつ増やす
for (int i = 0; i < 10; i += 2) {...}

・ループ変数を10から1ずつ1まで減らしていく
for (int i = 10; i > 0; i--) {...}

・ループ変数を初期化しない
for (; i < 10; i++) {...}

・繰り返し時の処理を行わない
for (int i = 0; i < 10;) {...}

●「繰り返し」の中断方法2種類
・「break文」:「while文やfor文による繰り返しをすぐに(繰り返し自体を)中断したい」場合に利用する。
・「continue文」:「今の周だけを中断して、次の周に進む」場合に利用する。

Main.java
//break文:1,2周目ときて、 3周目で中断する。
for (int i = 1; i < 10; i++){
  if (i == 3){
    break;
  }
  System.out.println(i);
}

//continue文:1,2周目通常通り処理される。 3周目のみ飛ばされる。4周目以降の処理が再開される。
for (int i = 1; i < 10; i++){
  if (i == 3){
    continue;
  }
  System.out.println(i);
}

●「無限ループ」
とは、強制停止されない限り「永久に繰り返しを続ける制御構造」のこと。
意図的に無限ループを作成するのは以下の2通り。
・while (true) {…処理…}
・for (;;) {…処理…}


制御構造のネスト(入れ子)

分岐や繰り返しの制御構造は、その中に別の制御構造を含むことが出来る。「分岐の中に分岐」「繰り返しの中に分岐」など。このような多重構造を「ネスト(入れ子)」という。

Main.java
//例「for文のループを二重にして九九の表を表示させる。」(=繰り返しの中に繰り返し)
public class Main {
  public static void main(String[] args) {
    for (int i = 1; i < 10; i++) { //iは1~9まで繰り返し
     for (int j = 1;j < 10;j++) { //jは1~9まで繰り返し
       System.out.print(i * j);  // 掛け算の結果を出力
       System.out.print(" ");    // 空白を出力
     }
     System.out.println("");     // 改行を出力
    }
  }
}
/*実行結果
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
・
・
9 18 27 36 45 54 63 72 81 
*/

上記は、内側のループが1周する度に、掛け算の結果が空白を挟みながら右へと表示される。
そして、内側のループが終了する(1つの段の掛け算の結果が全て出力される)と改行が入り、
外側のループの1周が終わる、これを外側のループが終了するまで繰り返す。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0