C言語は、順次構造、分岐構造、繰り返し構造という3つの主要な構造を持つ構造化言語です
本稿で解説する「条件分岐」は、分岐構造に対応します。
C言語では、非ゼロか非NULLの値を真(true)とし、ゼロまたはNULLを偽(false)として扱います。
if文
if(ブール式){
// ブール式が真の場合に実行される文
}
int age = 20;
if(age >= 18){
printf("成人です");
}
単一文の場合、波括弧なしで直接記述できます:
int age = 20;
if(age >= 18)
printf("成人です");
複数の文を実行する場合は波括弧が必要です。以下の例も同様です。
if-else文
if(ブール式){
// ブール式が真の場合に実行される文
}
else{
// ブール式が偽の場合に実行される文
}
int age = 15;
if(age >= 18){
printf("成人です");
}
else{
printf("未成年です");
}
ネストされたif文
if(ブール式1){
// ブール式1が真の場合に実行
if(ブール式2){
// ブール式2が真の場合に実行
}
}
int side1 = 5, side2 = 5, side3 = 8;
if(side1 == side2 || side1 == side3 || side2 == side3){
printf("二等辺三角形です\n");
if(side1 == side2 && side2 == side3){
printf("正三角形です\n");
}
}
if-else if文
if(条件1){
文ブロック1
}
else if(条件2){
文ブロック2
}
else if(条件3){
文ブロック3
}
else if(条件n){
文ブロックn
}
else{
文ブロックm
}
int score;
printf("点数を入力してください: ");
scanf("%d", &score);
if(score >= 90){
printf("優秀な成績です\n");
}
else if(score >= 80 && score < 90){
printf("良い成績です\n");
}
else if(score >= 60 && score < 80){
printf("合格ですが、更に努力が必要です\n");
}
else{
printf("不合格です\n");
}
「&&」の条件部分を削除するとどうなるでしょうか?
int score;
printf("点数を入力してください: ");
scanf("%d", &score);
if(score >= 90){
printf("優秀な成績です\n");
}
else if(score >= 80){
printf("良い成績です\n");
}
else if(score >= 60){
printf("合格です\n");
}
else{
printf("不合格です\n");
}
論理的には等価です。条件が満たされると、その後の条件は評価されません。
複数の条件を個別にチェックする場合は、複数のif文を使用します:
int number;
printf("数字を入力してください: ");
scanf("%d", &number);
if(number % 2 == 0){
printf("この数は2で割り切れます\n");
}
if(number % 3 == 0){
printf("この数は3で割り切れます\n");
}
if(number % 5 == 0){
printf("この数は5で割り切れます\n");
}
switch文
switch文は、変数が複数の値のいずれかと等しいかをテストする場合に使用します。各値はcaseと呼ばれ、テスト対象の変数は各switch caseと比較されます。
switch(式){
case 定数式:
文;
break; // 任意
case 定数式:
文;
break; // 任意
// case文は任意の数だけ使用可能
default: // 任意
文;
}
#include<stdio.h>
int main(){
printf("***********飲料メニュー***********\n");
printf("どの飲料をお選びですか?\n");
printf("1.オレンジジュース 2.カフェラテ\n");
printf("3.アイスティー 4.抹茶ラテ\n");
printf("その他:特製フルーツジュース\n");
printf("1-4:無料 その他:¥200/杯\n");
printf("****************************\n");
int selection;
scanf("%d", &selection);
switch(selection){
case 1:
printf("フレッシュなオレンジジュースをお楽しみください");
break;
case 2:
printf("濃厚なカフェラテをお楽しみください");
break;
case 3:
printf("爽やかなアイスティーをお楽しみください");
break;
case 4:
printf("和風の抹茶ラテをお楽しみください");
break;
default:
printf("季節限定の特製フルーツジュースです");
}
return 0;
}
switch文は以下のルールに従う必要があります:
- switch文の式は、整数型または列挙型、または整数型または列挙型に変換できる単一の変換関数を持つクラス型である必要があります
- 一つのswitch文には任意の数のcase文を使用できます。各case文の後には比較する値とコロンが続きます
- caseの定数式は、switchの変数と同じデータ型である必要があり、定数またはリテラルである必要があります
- テスト対象の変数がcaseの定数と等しい場合、そのcaseの文が実行され、break文に遭遇するまで続きます
- break文に遭遇すると、switchは終了し、制御フローはswitch文の次の行にジャンプします
- 各caseにbreak文を含める必要はありません。case文にbreakが含まれていない場合、制御フローは次のcaseに続行し、breakに遭遇するまで続きます
- switch文の末尾にオプションのdefault caseを含めることができます。default caseは、すべてのcaseが偽の場合にタスクを実行するために使用できます。default caseのbreak文は必須ではありません
ネストされたswitch文
switch(ch1){
case 'A' :
printf("このAは外部スイッチの一部です");
switch(ch2){
case 'A':
printf("このAは内部スイッチの一部です");
break;
case 'B':// 内部B caseのコード
}
break;
case 'B':// 外部B caseのコード
}
総合的な応用例
年と月を入力し、その年が閏年かどうかを判定し、その月の日数を出力します。
#include<stdio.h>
int main(){
int year, month;
bool isLeap = false;
printf("年と月をスペース区切りで入力してください: ");
scanf("%d %d", &year, &month);
if(year % 400 == 0) isLeap = true;
else if(year % 100 != 0 && year % 4 == 0) isLeap = true;
if(isLeap) printf("%d年は閏年です。\n", year);
else printf("%d年は閏年ではありません。\n", year);
switch(month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
printf("この月は31日です。\n");
break;
case 4:case 6:case 9:case 11:
printf("この月は30日です。\n");
break;
case 2:
printf("この月は%d日です。\n", (isLeap ? 29 : 28));
break;
}
return 0;
}