条件分岐
条件分岐は交差点の信号機のようなものです——条件が満たされれば一方の道を、そうでなければもう一方の道を進みます。プログラムは判断によって知性を持ちます。
if文
ifは最も基本的な条件分岐です。条件が真(非ゼロ)なら波括弧内のコードが実行され、偽(ゼロ)ならスキップされます。
C
#include <stdio.h>
int main(void) {
int score = 95;
if (score >= 90) {
printf("Excellent!\n");
}
printf("Program continues\n");
return 0;
}
TEXT
Excellent!
Program continues
💡 ヒント:
ifの後に文が1つだけの場合、波括弧は省略可能です。しかし、後から文を追加した際に波括弧の追加を忘れると論理エラーの原因になるため、常に波括弧を使うことを強く推奨します。
if-else文
if-elseは2つの分岐を提供します。条件が真ならifブロックが、偽ならelseブロックが実行されます。どちらか一方は必ず実行されます。
C
#include <stdio.h>
int main(void) {
int age = 16;
if (age >= 18) {
printf("You are an adult\n");
} else {
printf("You are a minor\n");
}
return 0;
}
TEXT
You are a minor
ダングリングelse問題
複数のif文がネストされている場合、elseは最も近いifと対になります。
C
#include <stdio.h>
int main(void) {
int a = 5, b = 0;
if (a > 10)
if (b > 0)
printf("A\n");
else
printf("B\n");
return 0;
}
elseは最初のifと対になっているように見えますが、実際は2番目のifと対になるため、何も出力されません。波括弧を追加すれば対関係が明確になります。
C
if (a > 10) {
if (b > 0) {
printf("A\n");
} else {
printf("B\n");
}
}
⚠️ 注意: 波括弧を常に使えば、ダングリングelse問題を完全に防ぐことができます。
if-else if-elseチェーン
複数の条件を順番に確認する必要がある場合、else ifで複数の分岐を連鎖させます。
C
#include <stdio.h>
int main(void) {
int score = 78;
if (score >= 90) {
printf("Grade: A\n");
} else if (score >= 80) {
printf("Grade: B\n");
} else if (score >= 70) {
printf("Grade: C\n");
} else if (score >= 60) {
printf("Grade: D\n");
} else {
printf("Grade: F\n");
}
return 0;
}
TEXT
Grade: C
else ifの条件は上から順に評価されます。一度条件が満たされると、以降の分岐はすべてスキップされます。条件の順序は重要です。
💡 ヒント: 効率を上げるため、最も成立しやすい条件を先に配置しましょう。範囲を扱う場合は大きい順に並べ、論理の隙間を防ぎます。
ネストされたif文
ifの中に別のifを入れることで、より細かな条件分岐が可能です。
C
#include <stdio.h>
int main(void) {
int age = 25;
char gender = 'M';
if (age >= 18) {
if (gender == 'M') {
printf("Adult male\n");
} else {
printf("Adult female\n");
}
} else {
printf("Minor\n");
}
return 0;
}
TEXT
Adult male
⚠️ 注意: ネストは3レベルを超えないようにしましょう。深すぎると可読性が低下します。複雑な条件は論理演算子でまとめるか、
else ifで平坦化できます。
switch-case文
switchは整数式の値に応じて一致するcase分岐へジャンプします。離散値による分岐に最適です。
基本構文
C
switch (expression) {
case constant1:
statement;
break;
case constant2:
statement;
break;
default:
statement;
break;
}
C
#include <stdio.h>
int main(void) {
int day = 3;
switch (day) {
case 1: printf("Monday\n"); break;
case 2: printf("Tuesday\n"); break;
case 3: printf("Wednesday\n"); break;
case 4: printf("Thursday\n"); break;
case 5: printf("Friday\n"); break;
case 6: printf("Saturday\n"); break;
case 7: printf("Sunday\n"); break;
default: printf("Invalid day\n"); break;
}
return 0;
}
TEXT
Wednesday
breakの重要性
switchがcaseに一致した後、breakまたはswitchの終わりに達するまで、そこから先のすべての文を実行します。これは「フォールスルー」と呼ばれます。
C
#include <stdio.h>
int main(void) {
int num = 2;
switch (num) {
case 1: printf("One\n");
case 2: printf("Two\n");
case 3: printf("Three\n");
default: printf("Default\n");
}
return 0;
}
TEXT
Two
Three
Default
⚠️ 注意:
breakの書き忘れはswitchで最もよくある間違いです。意図的なフォールスルーでない限り、各caseの最後に必ずbreakを追加しましょう。
フォールスルーで分岐をまとめる
複数のcaseラベルで同じ処理を実行したい場合、意図的にbreakを省略できます。
C
#include <stdio.h>
int main(void) {
char grade = 'B';
switch (grade) {
case 'A':
case 'B':
case 'C':
printf("Pass\n"); break;
case 'D':
printf("Retake\n"); break;
case 'F':
printf("Fail\n"); break;
default:
printf("Invalid grade\n"); break;
}
return 0;
}
TEXT
Pass
switchの制限
- 式は整数型(
int、char、enumなど)である必要があります。浮動小数点数や文字列は不可です caseの後の値はコンパイル時定数である必要があり、変数は使えませんcaseの値は重複してはいけません
条件演算子(三項演算子)
条件演算子?:は単純なif-else文を置き換えられます。第6回で紹介しましたが、ここではさらに使用例を示します。
C
#include <stdio.h>
int main(void) {
int a = -5;
int abs_a = a >= 0 ? a : -a;
printf("|%d| = %d\n", a, abs_a);
int x = 10, y = 10;
printf("%s\n", x == y ? "Equal" : "Not equal");
return 0;
}
TEXT
|-5| = 5
Equal
💡 ヒント: 条件演算子はネスト可能ですが、可読性が急速に低下します。1レベルを超えるネストには
if-elseを使いましょう。
例
BMIに基づいて体型を判定する、多分岐条件分岐の実例です。
C
#include <stdio.h>
int main(void) {
double weight = 70.0;
double height = 1.75;
double bmi = weight / (height * height);
printf("BMI: %.1f\n", bmi);
if (bmi < 18.5) {
printf("Underweight\n");
} else if (bmi < 24.0) {
printf("Normal\n");
} else if (bmi < 28.0) {
printf("Overweight\n");
} else {
printf("Obese\n");
}
return 0;
}
TEXT
BMI: 22.9
Normal
例
switchを使ったシンプルなメニュー選択の実装です。
C
#include <stdio.h>
int main(void) {
int choice = 2;
printf("===== Menu =====\n");
printf("1. New Game\n");
printf("2. Continue\n");
printf("3. Settings\n");
printf("4. Exit\n");
printf("================\n");
printf("Your choice: %d\n", choice);
switch (choice) {
case 1: printf("Starting new game!\n"); break;
case 2: printf("Loading save...\n"); break;
case 3: printf("Opening settings\n"); break;
case 4: printf("Exiting game\n"); break;
default: printf("Invalid choice\n"); break;
}
return 0;
}
TEXT
===== Menu =====
1. New Game
2. Continue
3. Settings
4. Exit
================
Your choice: 2
Loading save...
❓ よくある質問
Q
ifの後の波括弧はいつ省略できますか?A 構文的には
if/elseの後に文が1つだけの場合に省略可能ですが、後から文を追加した際のバグを防ぐため、常に使うことを推奨します。Q
switchで浮動小数点数や文字列を評価できますか?A いいえ。
switchは整数式のみを受け付けます。浮動小数点数も文字列も使えません。文字列の比較にはif-else ifチェーンを使ってください。Q
default分岐は省略できますか?A 構文的には可能ですが、想定外の値による無言のエラーを防ぐため、常に記述することを推奨します。
Q
else ifとネストされたifの違いは何ですか?A
else ifは平坦な多分岐構造で読みやすく、ネストされたifは階層的で条件同士が依存する場合に適しています。どちらでも書ける場合は、読みやすい方を選んでください。📖 まとめ
ifは単一条件、if-elseは二者選択、else ifは多分岐選択を扱います- 波括弧を常に使えば、ダングリングelse問題や将来の保守問題を防げます
switchは離散的な整数値による分岐に最適です。各caseのbreakを忘れないようにしましょうswitchのフォールスルーは分岐のまとめに使えますが、breakの書き忘れはよくあるバグの原因です- 三項演算子
?:は単純な二者選択に適しています。複雑な論理にはif-elseを使いましょう
📝 練習問題
- 整数を1つ読み込み、それが正の数、負の数、ゼロのいずれかを判定して結果を出力するプログラムを書いてください。
- 月番号(1〜12)を読み込み、
switchを使ってその月の日数を出力するプログラムを書いてください(閏年ではないと仮定し、2月は28日とします)。 - 文字を1つ読み込み、それが大文字、小文字、数字、その他の文字のいずれかを判定するプログラムを書いてください。



