コンテンツにスキップ

制御構文; Control Flow Statements

1. 制御構文とは

プログラムは基本的に上から下へ、1行ずつ順番に実行されます。しかし、すべての処理をただ順番に実行するだけでは、複雑な判断や繰り返し処理ができません。 制御構文は、このような「処理の流れ」を必要に応じて変えるための仕組みです。

Javaでは主に以下の3つの構造で処理を制御します:

# 構造 説明
1 順次構造 上から順に処理を実行する基本の流れ
2 分岐構造 条件によって処理を分ける(if文やswitch文など)
3 反復構造 同じ処理を繰り返す(for文やwhile文など)

この3つの構造だけで、あらゆるプログラムを組み立てることができるという考え方を「構造化定理」と呼びます。

1. 順次構造: 最も基本的な実行の流れで、上から順に処理されます。

flowchart TD
    Start([開始])
    Process1[処理1]
    Process2[処理2]
    Process3[処理3]
    End([終了])

    Start --> Process1 --> Process2 --> Process3 --> End

2. 分岐構造: 条件に応じて異なる処理を行います(例:if文)。

flowchart TD
    Start([開始])
    Process1[処理1]
    Decision{条件}
    Process2[処理2]
    Process3[処理3]
    End([終了])

    Start --> Process1 --> Decision
    Decision -- TRUE の場合 --> Process2 --> End
    Decision -- FALSE の場合 --> Process3 --> End

3. 反復構文: 同じ処理を何度も繰り返します(例:for文while文)。

flowchart TD
    Start([開始])
    Check{条件}
    Process[処理]
    End([終了])

    Start --> Check
    Check -- TRUE の場合 --> Process
    Process --> Check
    Check -- FALSE の場合 --> End

なぜ制御構文が重要か?

たとえば次のような場面では、制御構文が欠かせません:

  • 条件に応じて異なるメッセージを表示したい(例:成績が合格かどうか)
  • 複数の入力値を順に処理したい(例:データの集計)
  • 条件を満たすまで処理を繰り返したい(例:ゲームのループ処理)

制御構文を理解することで、プログラムが「状況に応じた行動」を取れるようになり、より柔軟で高度な処理が可能になります。

2. 比較演算子の基本

分岐や繰り返しを行う際には、「条件」を判定する必要があります。この条件式を作るために使うのが比較演算子です。 比較演算子は、2つの値を比較して真(true)か偽(false)かを返します。Javaでよく使われる比較演算子は以下の通りです:

比較演算子 意味 例(aが5, bが3) 結果
== 等しい a == b false
!= 等しくない a != b true
> より大きい a > b true
< より小さい a < b false
>= 以上 a >= b true
<= 以下 a <= b false

条件として使う例:

int score = 75;
if (score >= 60) {
    System.out.println("合格です");
}

このように、比較演算子によって得られた真偽値(boolean型)を使って、条件によって処理を分けることができます。

比較演算子の演算結果を確認するプログラム:

int a = 5;
int b = 3;

System.out.println(a == b); // false(等しくない)
System.out.println(a != b); // true(等しくないのでtrue)
System.out.println(a > b);  // true(5は3より大きい)
System.out.println(a < b);  // false(5は3より小さくない)
System.out.println(a >= b); // true(5は3以上)
System.out.println(a <= b); // false(5は3以下ではない)

注意点

  • =(代入演算子)と ==(比較演算子)を混同しないように注意しましょう。
  • 結果はすべて boolean 型(true または false)で返されます。

3. if文の基本構文

if 文は、プログラムに「条件分岐」を与えるための構文です。ある条件が成り立ったときだけ、特定の処理を実行するように書きます。日常の「もし〇〇だったら、××する」に対応しています。

基本構文:

if (条件式) {
    // 条件がtrueのときに実行される処理
}

プログラム例:

int score = 85;

if (score >= 80) {
    System.out.println("よくできました!");
}

出力結果:

よくできました!

この例では、score の値が 80 以上であれば「よくできました!」と表示されます。条件式が true であれば {} 内の文が実行され、false であれば何も実行されません。

ポイント

  • 条件式には、前の章で学んだ比較演算子を使うことが多いです。
  • {}(ブロック)は1行だけなら省略可能ですが、初心者のうちは必ずブロックで囲むことを推奨します。読みやすさとバグ防止のためです。
  • if 文だけでは「条件が成り立たなかったとき」の処理は書けません。これは次の if-else 文で学びます。

4. if / else文

if / else 文は、「条件が成り立つ場合の処理」と「条件が成り立たない場合の処理」の両方を記述したいときに使います。いわば「そうでなければ〜する」を明示的に書く構文です。

基本構文

if (条件式) {
    // 条件がtrueのときに実行される処理
} else {
    // 条件がfalseのときに実行される処理
}

例:

int score = 65;

if (score >= 80) {
    System.out.println("よくできました!");
} else {
    System.out.println("がんばりましょう!");
}

出力結果:

がんばりましょう!

ポイント:

  • if の条件が true なら if の中身だけが実行され、false なら else の中身が実行されます。
  • ifelse のどちらか一方のブロックだけが必ず1回実行されます。
  • 「2択」のような状況で使うと、処理を簡潔に表現できます。

5. if / else if / else文

if / else if / else 文は、複数の条件を順番に評価して、最初に成り立った条件の処理だけを実行したいときに使います。

基本構文:

if (条件1) {
    // 条件1がtrueのときに実行される処理
} else if (条件2) {
    // 条件1がfalseで、条件2がtrueのときに実行
} else {
    // すべての条件がfalseのときに実行
}

例:

int score = 72;

if (score >= 90) {
    System.out.println("たいへんよくできました!");
} else if (score >= 70) {
    System.out.println("よくできました!");
} else {
    System.out.println("がんばりましょう!");
}

出力結果:

よくできました!

この例では、score が70以上90未満なので、else if の部分が実行されます。

ポイント

  • 上から順に条件を評価し、最初にtrueになった処理だけが実行されます。
  • すべての条件がfalseのときは、else が実行されます(省略可能)。
  • 条件が3つ以上ある場合でも、コードを読みやすく整理できます。

6. ネストされたif文(入れ子構造)

if 文の中にさらに if 文を書くことで、より細かい条件分岐ができるようになります。これを「ネスト(入れ子)された if 文」と呼びます。

基本構文

if (条件1) {
    if (条件2) {
        // 条件1と条件2の両方がtrueのとき実行される
    } else {
        // 条件1がtrue かつ 条件2がfalseのとき
    }
} else {
    // 条件1がfalseのとき
}

例:

int score = 85;
boolean submitted = true;

if (submitted) {
    if (score >= 80) {
        System.out.println("提出もバッチリ!優秀です!");
    } else {
        System.out.println("提出はOK、でももう少し頑張ろう!");
    }
} else {
    System.out.println("まずは提出してください!");
}

出力結果:

提出もバッチリ優秀です

このように、条件が複雑な場合はネストして使うことで判断の分岐を細かくコントロールできます。ネストは便利ですが、深くなりすぎると読みにくくなるので注意が必要です。

7. switch文の活用

switch 文は、変数の値によって分岐処理を行う構文です。特に「値に応じて多数の選択肢を処理する」場合に、if / else if よりもすっきりと記述できるのが特徴です。

基本構文

switch (変数) {
case 値1:
    // 値1の場合の処理
    break;
case 値2:
    // 値2の場合の処理
    break;
default:
    // 上記以外の場合の処理
}

ポイント解説*

  • case は、条件に一致する値に応じた処理を記述します
  • break は、各ケースの処理が終わったら分岐を終了します(省略すると次のケースに流れます)
  • default は、どのケースにも一致しなかった場合に実行されます(elseのような役割)

例:

int day = 3;

switch (day) {
    case 1:
        System.out.println("月曜日です");
        break;
    case 2:
        System.out.println("火曜日です");
        break;
    case 3:
        System.out.println("水曜日です");
        break;
    default:
        System.out.println("他の曜日です");
}

出力結果:

水曜日です

注意点

  • switchintcharStringenum 型などに使用できます(booleanfloat は使えません)。
  • break を忘れると意図しない分岐の連続実行が起こるため注意しましょう(これをフォールスルーと呼びます)。

switch式(Java 14以降)

従来との違い

従来の switch 文は命令文(statement)として使われ、処理だけを行いましたが、 switch式(expression) は値を返すことができるのが大きな違いです。

基本構文

String result = switch () {
    case 値1 -> "結果1";
    case 値2 -> "結果2";
    default -> "その他";
};
特徴・メリット 説明
値を返せる 式として使えるため、switchの結果を変数に直接代入できる
記述が簡潔 -> を使うことで、break{} を省略可能
安全性が高い break の書き忘れによるバグが起きにくい
複数条件に対応可能 case 1, 2 -> のように、同じ処理をまとめて記述できる
複雑な処理にも対応 ブロックと yield を使うことで、複数行の処理も記述できる

例:曜日番号から名前を得る

int day = 3;

String dayName = switch (day) {
    case 1 -> "月曜日";
    case 2 -> "火曜日";
    case 3 -> "水曜日";
    case 4 -> "木曜日";
    case 5 -> "金曜日";
    case 6, 7 -> "週末";
    default -> "不明な日";
};

System.out.println(dayName);

出力:

水曜日

複雑な処理が必要な場合(ブロック付き):

String result = switch () {
    case 1 -> {
        // 複数行処理も可能
        System.put.println("処理中");
        yield "結果1";
    }
    default -> "その他";
};

まとめ:

  • switch式 はコードの簡潔さと安全性を高めるモダンな書き方。
  • Javaの初学者にも今後は基本の一部として学んでおく価値がある構文です。

8. 条件演算子(三項演算子)

◆ 条件演算子とは?

条件演算子(または三項演算子)は、if / else 文を1行で簡潔に書ける構文です。

基本構文

条件式 ? 値1 : 値2
  • 条件式が true の場合は 値1 が選ばれ、
  • 条件式が false の場合は 値2 が選ばれます。

◆ 例:数値の大小を比較

int a = 10;
int b = 20;
String result = (a > b) ? "aの方が大きい" : "bの方が大きい";
System.out.println(result);

このコードは、if / else を次のように書いたのと同じ意味です:

String result;
if (a > b) {
    result = "aの方が大きい";
} else {
    result = "bの方が大きい";
}

◆ 使いどころと注意点

使いどころ

  • 代入や戻り値に条件分岐を含めたいとき
  • 処理が1行で済むシンプルな条件
String grade = (score >= 60) ? "合格" : "不合格";

注意点

複雑な条件やネスト(入れ子)は可読性を損なうため避けましょう。

// 悪い例:ネストした三項演算子
String result = (x > 0) ? ((x < 10) ? "1〜9" : "10以上") : "0以下";

◆ まとめ

項目 説明
構文 条件 ? 値1 : 値2
特徴 if / else を1行で簡潔に記述可能
主な用途 代入や出力など、簡単な条件分岐処理に適する
注意点 複雑な処理やネストは可読性が下がるため避ける

9. よくある間違いと注意点

Javaの制御構文を使ううえで、初心者が陥りやすい間違いや注意しておきたいポイントを紹介します。

比較演算子と代入演算子の混同

Javaでは、比較をする際に == を使いますが、誤って =(代入)を書いてしまうケースがよくあります。

int x = 5;

if (x = 3) {  // 誤り!代入になっている
    System.out.println("3です");
}

このコードは、x = 3 という代入文が評価され、その結果が true 扱い(非ゼロ)となるため、文法上のエラーにはならず実行されますが、意図した動作にはなりません。

正しくは:

if (x == 3) {
    System.out.println("3です");
}

ブロック {} を省略した場合の罠

ifelse の直後の処理が1行だけの場合、ブロック {} を省略できますが、後から行を追加したときに意図しない動作となるリスクがあります。

if (x > 0)
    System.out.println("正の数です");
    System.out.println("処理完了");  // if文の外と見なされる

この例では、下の printlnif の中ではなく、常に実行されてしまいます。 安全のため、常にブロック {} を使う習慣をおすすめします。 このような落とし穴を理解しておくことで、より安全で読みやすいコードを書くことができます。

10. 演習問題

問題1:if文の基本

次のコードは、入力された点数が60点以上かどうかを判定するものです。空欄【A】を埋めて、合格か不合格を表示させてください。

int score = 75;
if (A) {
    System.out.println("合格");
}

[選択肢]

  1. score >= 60
  2. score == 60
  3. score > 75

問題2:if / else文

年齢に応じて「大人」か「子供」を判定します。正しく動作するように、if文を完成させましょう。

int age = 17;
if (A) {
    System.out.println("大人");
} else {
    System.out.println("子供");
}

[選択肢]

  1. age > 20
  2. age >= 18
  3. age < 18

問題3:if / else if / else文

次のコードは、点数に応じて成績を判定します。空欄を埋めて、以下の条件で表示がされるようにしてください。: - 80点以上 → 「優秀」 - 60点以上 → 「合格」 - それ以外 → 「再試験」

int score = 65;
if (A) {
    System.out.println("優秀");
} else if (B) {
    System.out.println("合格");
} else {
    System.out.println("再試験");
}

[選択肢]

  1. score >= 80
  2. score >= 60
  3. score < 60

問題4:入れ子のif文(ネスト)

次のコードは、年齢と性別に応じてメッセージを表示します。空欄を埋めて、20歳以上の男性に「成人男性です」と表示させましょう。

int age = 25;
String gender = "male";

if (age >= 20) {
    if (A) {
        System.out.println("成人男性です");
    }
}

[選択肢]

  1. gender.equals(“male”)
  2. gender == “male”
  3. gender = “male”

問題5:switch文の活用

次のコードは、曜日に応じてメッセージを表示します。正しい箇所にbreakを入れて、不要な出力が行われないようにしてください。

String day = "Tuesday";
switch (day) {
    case "Monday":
        System.out.println("週の始まりです");
        A
    case "Tuesday":
        System.out.println("火曜日です");
        B
    default:
        System.out.println("その他の曜日です");
}

[選択肢]

  1. break;
  2. continue;
  3. return;

問題6:三項演算子

三項演算子を使って、年齢に応じてメッセージを変えるコードを完成させてください。

int age = 20;
String result = (age >= 18) ? "成人" : A;
System.out.println(result);

[選択肢]

  1. “未成年”
  2. “成人”
  3. “子供”

問題7:よくある間違い

次のコードは、20歳以上なら「成人」と表示するはずですが、意図通りに動作しません。間違っている部分を選んでください。

int age = 25;
if (age = 20) {
    System.out.println("成人");
}

[選択肢]

  1. if文の条件で代入演算子(=)を使っている
  2. 25は20より大きいからif文は実行されない
  3. printlnの文法が間違っている