対象:C言語経験者 / C言語との差分を中心に、試験頻出のswitch文フォールスルーを理解します
if文の構文はC言語と全く同じです。条件式に boolean 型の値を使う点だけ意識しておきましょう。
if (a > 0) {
printf("正\n");
} else if (a < 0) {
printf("負\n");
} else {
printf("ゼロ\n");
}
if (a > 0) {
System.out.println("正");
} else if (a < 0) {
System.out.println("負");
} else {
System.out.println("ゼロ");
}
// C言語ではOKだがJavaではコンパイルエラー
int flag = 1;
if (flag) { ... } // エラー:int は boolean ではない
// Javaではこう書く
boolean flag = true;
if (flag) { ... } // OK
// または比較式にする
int n = 1;
if (n != 0) { ... } // OK
boolean 型である必要があります。if (n >= 0)」のような記述が問われます。
C言語では == と書くつもりが = になっても動いてしまうため、発見しにくいバグになることがありました。
int n = 3;
if (n = 5) {
// == と書くつもりが = になった
// n に 5 が代入され、0以外なので
// 常に true になるバグ
printf("ここが実行される\n");
}
int n = 3;
if (n = 5) {
// コンパイルエラー!
// int を boolean に使えないと
// コンパイル時に教えてくれる
}
boolean」と決めたことで、= と == の書き間違いをコンパイル時に検出できます。エラーを実際に確認しましょう
05_Grade フォルダに IfError.java を作って、あえてエラーになるコードを書いてみましょう。
public class IfError {
public static void main(String[] args) {
int n = 5;
// ① int をそのまま条件式に使う → エラー
if (n) {
System.out.println("これはエラー");
}
// ② = を == と書き間違える → エラー
if (n = 10) {
System.out.println("これもエラー");
}
}
}
VSCode上での確認:
incompatible types: int cannot be converted to boolean確認できたら、次のように修正して正しく動くことも確認しましょう:
public class IfError {
public static void main(String[] args) {
int n = 5;
// 修正① 比較式にする
if (n != 0) {
System.out.println("n は 0 ではない");
}
// 修正② = を == に直す
if (n == 10) {
System.out.println("n は 10");
} else {
System.out.println("n は 10 ではない");
}
}
}
switch (x) {
case 1:
printf("one\n");
break;
case 2:
printf("two\n");
break;
default:
printf("other\n");
}
switch (x) {
case 1:
System.out.println("one");
break;
case 2:
System.out.println("two");
break;
default:
System.out.println("other");
}
| 項目 | C言語 | Java |
|---|---|---|
| 条件式に使える型 | 整数型のみ | 整数型・char・String・enum |
条件式に boolean | 使えない | 使えない(同じ) |
条件式に float/double | 使えない | 使えない(同じ) |
フォールスルー(break 忘れ) | 起きる | 起きる(同じ) |
String を switch の条件式に使えます。これはC言語にはない機能です。
// JavaではStringをswitchに使える
String day = "Mon";
switch (day) {
case "Mon":
System.out.println("月曜日");
break;
case "Tue":
System.out.println("火曜日");
break;
default:
System.out.println("その他");
}
break を書かないと、次の case に処理が「落ちていく」現象をフォールスルー(fall through)と言います。これはC言語と同じ動作ですが、試験で繰り返し出題されます。
break がない case は、床に穴が空いているようなイメージです。処理が次の case に落ちていきます。
case 0 に break がないため、a=0 のとき case 1 にも処理が流れます(フォールスルー)。
「複数の case に同じ処理をさせたい」ときに意図的に使うこともあります。
// 平日かどうかを判定する例
switch (day) {
case 1: // 月曜
case 2: // 火曜
case 3: // 水曜
case 4: // 木曜
case 5: // 金曜
System.out.println("平日");
break;
case 6: // 土曜
case 7: // 日曜
System.out.println("休日");
break;
}
println のあとに break を書き忘れるのは意図しないフォールスルーで、バグになります。
| 型 | switch の条件式に使えるか |
|---|---|
int(と byte, short, char) | 使えます |
String | 使えます(Java 7以降。C言語にはない) |
enum(列挙型) | 使えます(後の単元で学びます) |
long | 使えません(コンパイルエラー) |
float / double | 使えません(コンパイルエラー) |
boolean | 使えません(コンパイルエラー) |
long を使った → コンパイルエラー」という誤りパターンが出題されます。int の範囲に収まる整数型のみ使えます(long は範囲が大きすぎるため不可)。
実習1
05_Grade フォルダに Grade.java を作って実行しましょう。
public class Grade {
public static void main(String[] args) {
int score = 75;
// if-else if-else による成績判定
if (score >= 90) {
System.out.println("評価: A");
} else if (score >= 70) {
System.out.println("評価: B");
} else if (score >= 50) {
System.out.println("評価: C");
} else {
System.out.println("評価: D(不合格)");
}
// 条件演算子との比較(同じ判定を1行で)
String grade = (score >= 60) ? "合格" : "不合格";
System.out.println("合否: " + grade);
}
}
実行結果(score = 75 の場合):
| # | 変えてみること | 確認ポイント |
|---|---|---|
| 1 | score を 90, 70, 50, 30 に変えて4パターン確認する |
境界値(ちょうど70や90)でどちらに分類されるか確認しましょう |
| 2 | 条件を score > 90(= なし)に変えてみる |
score = 90 のとき評価が A → B に変わることを確認しましょう。境界条件のミスはよくあるバグです |
| 3 | if (score) と書いてみる(条件に int を直接使う) |
コンパイルエラーになることを確認しましょう。C言語との違いです |
実習2
06_Switch フォルダに Switch.java を作って実行しましょう。
public class Switch {
public static void main(String[] args) {
// ① フォールスルーの確認(break なし)
int a = 0;
System.out.println("--- a=" + a + " ---");
switch (a) {
case 0:
System.out.println("zero");
// break がないので次に落ちる
case 1:
System.out.println("one");
break;
case 2:
System.out.println("two");
break;
}
// ② 試験第67回 問4(23) と同じパターン
int val = 4;
System.out.println("\n--- switch(val - val/2*2), val=" + val + " ---");
switch (val - val / 2 * 2) {
case 0:
System.out.println("zero");
// break なし → フォールスルー
case 1:
System.out.println("one");
}
// ③ Stringをswitchに使う(Javaだけの機能)
String color = "red";
System.out.println("\n--- color=" + color + " ---");
switch (color) {
case "red":
System.out.println("赤");
break;
case "blue":
System.out.println("青");
break;
default:
System.out.println("その他");
}
}
}
実行結果:
val - val/2*2 がなぜ 0 になるのか確認しましょうval = 4 のとき:
val / 2 → 整数除算で 4 / 2 = 2val / 2 * 2 → 2 * 2 = 4(* と / は同じ優先順位で左から評価)val - val/2*2 → 4 - 4 = 0これは偶数のとき 0、奇数のとき 1 になる計算です。
val % 2(2で割った余り)と同じ意味になります。
第67回 問4(23) ではこの計算が case 0 にマッチし、break がないため case 1 にもフォールスルーして "zero" と "one" が両方出力されます。
| # | 変えてみること | 確認ポイント |
|---|---|---|
| 1 | ① の case 0: の直後に break; を追加する |
フォールスルーが止まって "zero" だけ表示されることを確認しましょう |
| 2 | ② の val を 3(奇数)に変える |
3 - 3/2*2 = 3 - 1*2 = 3 - 2 = 1 となり case 1 だけが実行されることを確認しましょう |
| 3 | ③ の color を "RED"(大文字)に変える |
String の switch は大文字小文字を区別します。"その他" になることを確認しましょう |
頻出ポイント
| よく問われること | 正しい答え |
|---|---|
switch に break がないとき | 次の case に処理が流れる(フォールスルー) |
| switch の条件式に使えない型 | long, float, double, boolean |
switch の条件式に String | 使えます(Java 7以降) |
| if の条件式に整数を直接使う | コンパイルエラー(boolean 型が必要) |
public class Q {
public static void main(String[] args) {
int a = 4;
switch (a - a / 2 * 2) {
case 0:
System.out.println("zero");
case 1:
System.out.println("one");
}
}
}
① a - a/2*2 = 4 - 2*2 = 0 なので case 0 に入ります。
② case 0 に break がないためフォールスルーして case 1 も実行されます。
public class Q2 {
public static void main(String[] args) {
int n = -5;
if (n >= 0) {
System.out.print("Perl");
} else if (n < -3) {
System.out.print("PHP");
} else {
System.out.print("Python");
}
}
}
n = -5 は n >= 0 を満たさず、n < -3(-5 < -3)を満たすので "PHP" が出力されます。
| ポイント | 内容 |
|---|---|
| if 文 | C言語と同じ。条件式は必ず boolean 型(整数不可) |
| switch のフォールスルー | break がないと次の case に処理が流れる。試験最頻出 |
| switch の条件式 | int, char, String, enum が使える。long, float, boolean は不可 |
| String の switch | Java 7以降で使える。C言語にはない機能 |
| 意図的フォールスルー | 処理なしの case を並べて複数の値に同じ処理をさせる |