C言語の条件分岐、プログラミングを始めたばかりだと、ちょっと戸惑うポイントかもしれませんね。「もし〇〇だったら△△する」みたいな処理、どう書けばいいんだっけ? と手が止まってしまうこともあるでしょう。
この記事では、C言語プログラミングのキホン中のキホン、条件分岐の命令であるif
文とswitch
文について、ゼロからしっかり解説していきます! 基本的な書き方から、実際のプログラム例、そしてうっかりハマりがちな注意点まで、まるっと網羅しています。
読み終わるころには、「なるほど、そういうことか!」と条件分岐の仕組みが腹落ちして、自信を持ってプログラムを書けるようになっているはず。さあ、一緒にC言語の条件分岐をマスターしちゃいましょう!
この記事を読むとわかること
- 条件分岐ってそもそも何のためにあるの? という基本の考え方
if
文、else
文、else if
文の正しい書き方と使いどころ- たくさんの選択肢があるときに便利な
switch
文の書き方と使い方 - 条件分岐を組み合わせる「入れ子構造」の考え方
- プロも気をつける条件分岐の注意点
C言語の条件分岐とは?プログラムの流れを変える基本
プログラムって、基本的には書かれた順番通りに上から下へと実行されていきます。でも、それだけだと単純な動きしかできませんよね?
例えば、テストの点数を入力したら、点数に応じて「合格!」とか「もう少し頑張ろう!」みたいに表示を変えたいとき、どうしますか?
あるいは、自動販売機でお金を入れてボタンを押したら、投入金額が足りているかチェックして、足りていれば商品を出して、足りなければ「お金が足りません」と表示したいですよね。
そんなふうに、ある条件が満たされているかどうかを判断して、その結果によって次に実行する処理を変える仕組み、それが「条件分岐」なんです。
条件分岐があるからこそ、プログラムは状況に応じて賢く振る舞えるようになります。C言語では、そのための命令として主にif
文とswitch
文が用意されています。まずは、一番よく使うif
文から見ていきましょう!
C言語の条件分岐の主役!if文の基本的な書き方
if
文は、C言語の条件分岐で最もよく使われる、まさに主役級の命令です。「もし〜ならば、〇〇する」という処理を実現します。
基本的な書き方は以下の形です。
if (条件式) { // 条件式が真(True)のときに実行したい処理 }
if
の後のカッコ()
の中に「条件式」を書きます。条件式には、「変数の値が10より大きいか?(score > 10
)」とか、「入力された文字が 'a' と同じか?(input == 'a'
)」といった、結果が「はい(真)」か「いいえ(偽)」で答えられるような式を書きます。
そして、条件式の結果が「はい(真、True)」だった場合だけ、続く中括弧{}
で囲まれた部分の処理が実行されます。もし結果が「いいえ(偽、False)」だったら、中括弧{}
の中の処理はまるっと無視(スキップ)されます。
条件式でよく使われる比較演算子も覚えておきましょう。
==
: 等しい!=
: 等しくない<
: より小さい>
: より大きい<=
: 以下>=
: 以上
まずはif
文の基本形をしっかり押さえてくださいね!
条件に合わない場合の処理:elseの使い方
if
文だけだと、条件に合ったときしか処理を実行できません。「もし条件に合わなかったら、別の処理をしたいんだけど…」という場面もたくさんありますよね。
そんなときに登場するのがelse
です。else
は単独では使えず、必ずif
文とセットで使います。「もし〜ならば処理A、そうでなければ処理B」という流れを作れます。
書き方は以下の通り。
if (条件式) { // 条件式が真(True)のときに実行したい処理 (処理A) } else { // 条件式が偽(False)のときに実行したい処理 (処理B) }
if
の条件式が真なら中括弧{}
の中の処理Aが実行され、偽ならelse
の後の中括弧{}
の中の処理Bが実行されます。どちらか一方だけが必ず実行される、というシンプルな二択の分岐です。
例えば、「もし点数が60点以上なら『合格』、そうでなければ『不合格』と表示する」といった処理が簡単に書けますね。
複数の条件を順番に判定:else ifの使い方
「条件Aなら処理1、条件Aじゃないけど条件Bなら処理2、どちらでもなければ処理3」みたいに、選択肢が3つ以上ある場合はどうしましょう?
そんなときはelse if
の出番です。if
文とelse
文の間に、いくつでもelse if
を繋げることができます。
書き方のイメージはこんな感じです。
if (条件式1) { // 条件式1が真(True)のときに実行したい処理 (処理1) } else if (条件式2) { // 条件式1が偽で、かつ条件式2が真(True)のときに実行したい処理 (処理2) } else if (条件式3) { // 条件式1も2も偽で、かつ条件式3が真(True)のときに実行したい処理 (処理3) } else { // 上のどの条件式も偽(False)だったときに実行したい処理 (処理4) }
ポイントは、条件式が上から順番にチェックされることです。最初に真になった条件式のブロックだけが実行され、残りのelse if
やelse
は無視されます。もし、どのelse if
の条件式も偽だった場合は、最後のelse
ブロックが実行されます(else
は省略することも可能です)。
これで、複雑な条件分岐も表現できるようになりますね! テストの点数で「優」「良」「可」「不可」を判定する、みたいな処理もelse if
を使えば実現できます。
C言語の条件分岐を使いこなす!if文の実践サンプル
理屈がわかったところで、実際にif
、else if
、else
を使ったプログラムを見てみましょう。ここでは、入力された点数に応じて成績を表示するプログラムを作成してみます。
▼ サンプルプログラム (score_check.c)
#include <stdio.h> int main(void) { int score; printf("点数を入力してください (0-100): "); scanf("%d", &score); // キーボードから整数値を入力してもらう printf("あなたの成績は "); if (score < 0 || score > 100) { // まず、ありえない点数かチェック printf("不正な点数です。\n"); } else if (score >= 80) { printf("優 です!素晴らしい!\n"); } else if (score >= 65) { printf("良 です!いい調子!\n"); } else if (score >= 50) { printf("可 です。もう少し!\n"); } else { // 0点以上50点未満の場合 printf("不可 です...。頑張りましょう!\n"); } return 0; }
▼ 実行結果の例1 (85点を入力した場合)
点数を入力してください (0-100): 85 あなたの成績は 優 です!素晴らしい!
▼ 実行結果の例2 (60点を入力した場合)
点数を入力してください (0-100): 60 あなたの成績は 可 です。もう少し!
▼ プログラムの解説
- まず
scanf
で点数を入力してもらいます。 - 最初の
if
で、点数が0未満または100より大きい、つまり不正な値でないかをチェックしています。(||
は「または」の意味の論理演算子です) - 次に
else if (score >= 80)
で80点以上かをチェック。真なら「優」と表示して、それ以降のelse if
,else
は実行されません。 - 80点未満だった場合、次の
else if (score >= 65)
で65点以上かをチェック。真なら「良」と表示。 - 65点未満だった場合、次の
else if (score >= 50)
で50点以上かをチェック。真なら「可」と表示。 - 上のどの条件にも当てはまらなかった場合(つまり0点以上50点未満)、最後の
else
ブロックが実行され、「不可」と表示されます。
このように、if
とelse if
、else
を組み合わせることで、複数の条件に応じた処理の振り分けが実現できるのが分かりますね。
多数の選択肢に便利!C言語の条件分岐:switch文の書き方
if-else if
をたくさん繋げることでも複数の条件分岐は書けますが、ある「特定の値」と一致するかどうかで処理を分けたい場合、もっとスッキリ書ける命令があります。それがswitch
文です!
例えば、メニュー番号を選んで処理を分岐させる、といった場面で活躍します。
基本的な書き方は以下の通りです。
switch (式) { case 定数1: // 式の値が定数1と一致した場合の処理 break; // switch文を抜ける case 定数2: // 式の値が定数2と一致した場合の処理 break; // switch文を抜ける case 定数3: // 式の値が定数3と一致した場合の処理 break; // switch文を抜ける default: // 式の値がどのcaseの定数とも一致しなかった場合の処理 break; // defaultの場合も念のためbreakを書くことが多い }
switch
の後のカッコ()
の中に、比較したい変数や式を書きます(整数か文字の値になるものが一般的)。
その値が、case
の後ろに書かれた「定数」(具体的な数値や文字)と一致するかどうかを順番に見ていきます。
一致するcase
が見つかると、そのcase
の下に書かれた処理が実行されます。
ここでとても大事なのがbreak;
です。各case
の処理の最後にbreak;
を書かないと、一致したcase
の後にある次のcase
の処理も続けて実行されてしまう(これをフォールスルーと呼びます)ので、通常は処理の終わりにbreak;
を書いて、switch
文全体を抜けるようにします。
default:
は、どのcase
にも一致しなかった場合に実行される処理を書く場所です。if
文でいう最後のelse
のような役割ですね。default
は省略することも可能です。
if
文は範囲(〇〇以上、〇〇未満)で条件を指定するのに向いていますが、switch
文は特定の値(〇〇と等しい)で分岐するのに向いています。うまく使い分けましょう!
switch文を使う場面とサンプルプログラム
switch
文は、変数の値が「1だったら処理A」「2だったら処理B」「3だったら処理C」のように、特定の値ごとに処理を分けたい場合に特に便利です。
簡単なメニュー選択プログラムでswitch
文の使い方を見てみましょう。
▼ サンプルプログラム (menu_select.c)
#include <stdio.h> int main(void) { int choice; printf("=== ドリンクメニュー ===\n"); printf("1: コーヒー\n"); printf("2: 紅茶\n"); printf("3: オレンジジュース\n"); printf("番号を選んでください (1-3): "); scanf("%d", &choice); switch (choice) { case 1: printf("コーヒーですね。少々お待ちください。\n"); break; // このbreakを忘れると、紅茶のメッセージも表示されてしまう! case 2: printf("紅茶ですね。かしこまりました。\n"); break; case 3: printf("オレンジジュースですね。どうぞ!\n"); break; default: // 1, 2, 3 以外が入力された場合 printf("申し訳ありません。メニューにない番号です。\n"); break; } return 0; }
▼ 実行結果の例1 (1を入力した場合)
=== ドリンクメニュー === 1: コーヒー 2: 紅茶 3: オレンジジュース 番号を選んでください (1-3): 1 コーヒーですね。少々お待ちください。
▼ 実行結果の例2 (5を入力した場合)
=== ドリンクメニュー === 1: コーヒー 2: 紅茶 3: オレンジジュース 番号を選んでください (1-3): 5 申し訳ありません。メニューにない番号です。
▼ プログラムの解説
- メニューを表示し、
scanf
で番号を入力してもらいます。 switch (choice)
で、入力された変数choice
の値に基づいて分岐を開始します。case 1:
もしchoice
が1なら、「コーヒーですね…」のメッセージを表示し、break;
でswitch
文を抜けます。case 2:
もしchoice
が2なら、「紅茶ですね…」のメッセージを表示し、break;
で抜けます。case 3:
もしchoice
が3なら、「オレンジジュースですね…」のメッセージを表示し、break;
で抜けます。default:
もしchoice
が1, 2, 3のいずれでもなかった場合、「メニューにない番号です」のメッセージを表示します。
もしcase 1:
のbreak;
を書き忘れると、1を入力したときに「コーヒーですね…」に加えて「紅茶ですね…」まで表示されてしまいます。break;
の書き忘れには十分注意しましょうね!
C言語の条件分岐を組み合わせる!入れ子(ネスト)構造
条件分岐は、さらにその中に条件分岐を書くことができます。これを「入れ子」とか「ネスト」と呼びます。
例えば、if
文の処理の中に、さらに別のif
文を書くことができます。
if (条件式A) { // 条件式Aが真のときの処理 if (条件式B) { // 条件式Aが真で、かつ条件式Bも真のときの処理 } else { // 条件式Aが真で、かつ条件式Bは偽のときの処理 } } else { // 条件式Aが偽のときの処理 }
こんなふうに、ある条件を満たした場合に、さらに細かい条件で処理を分けたいときに使います。「もしユーザーIDが合っていて、さらにパスワードも合っていたらログイン成功」みたいな処理は、まさにネスト構造の出番です。
ネストは何段階でも深くできますが、深くしすぎるとプログラムがどこで何をやっているのか非常に分かりにくくなってしまいます。
ネストを使うときは、インデント(字下げ)をしっかり行うのがマナーです。どのif
がどのelse
に対応しているのか、処理のブロックがどこからどこまでなのかを視覚的に分かりやすくするために、インデントは絶対に守りましょう! エディタの自動整形機能を使うのも良いですね。
ネスト構造のサンプルと可読性について
簡単なネスト構造のサンプルを見てみましょう。ここでは、年齢と性別を入力してもらい、条件に応じてメッセージを変えてみます。
▼ サンプルプログラム (nested_if.c)
#include <stdio.h> int main(void) { int age; char gender; // 'm' or 'f' printf("年齢を入力してください: "); scanf("%d", &age); // scanfの直後に改行文字が残るのを防ぐおまじない while(getchar() != '\n'); printf("性別を入力してください (m:男性, f:女性): "); scanf("%c", &gender); if (age >= 20) { printf("あなたは成人ですね。"); if (gender == 'm') { printf("男性の方ですね。\n"); } else if (gender == 'f') { printf("女性の方ですね。\n"); } else { printf("性別の入力が正しくありません。\n"); } } else if (age >= 0) { // 0歳以上20歳未満の場合 printf("あなたは未成年ですね。"); if (gender == 'm') { printf("男の子ですね。\n"); } else if (gender == 'f') { printf("女の子ですね。\n"); } else { printf("性別の入力が正しくありません。\n"); } } else { // 年齢がマイナスの場合 printf("年齢の入力が正しくありません。\n"); } return 0; }
▼ 実行結果の例 (年齢30, 性別m を入力した場合)
年齢を入力してください: 30 性別を入力してください (m:男性, f:女性): m あなたは成人ですね。男性の方ですね。
▼ プログラムの解説
- 年齢と性別を入力してもらいます。(
scanf("%c",...)
の前のwhile
文は、前のscanf
で残った改行コードを読み飛ばすためのテクニックです) - 最初の
if (age >= 20)
で成人か未成年(または不正な入力)かを判定します。 - もし成人(
age >= 20
が真)なら、「あなたは成人ですね。」と表示した後、さらに内側のif
文で性別を判定し、男性か女性か(または不正な入力か)を表示します。 - もし未成年(
age >= 0
が真)なら、「あなたは未成年ですね。」と表示した後、同じように内側のif
文で性別を判定します。 - もし年齢がマイナスなら、最後の
else
でエラーメッセージを表示します。
このように、条件の中にさらに条件を書くことで、より細かな処理の分岐ができます。
ただし、見ての通り、ネストが深くなるとコードが右にどんどんズレていき、全体像を把握するのが少し大変になってきますよね。
3段階以上の深いネストは、プログラムを読みにくくする原因になりがちです。あまりにネストが深くなるようなら、処理を別の関数に分けるなど、もっと分かりやすい書き方がないか考えてみるのも良いでしょう。
C言語の条件分岐を使う上での注意点
条件分岐は便利ですが、いくつか気をつけないと意図しない動きをしてしまう落とし穴があります。ここでは代表的な注意点を挙げておきますね。
比較の==
と代入の=
を間違えない!
これは本当に初心者がよくやるミスナンバーワンかもしれません! if
文の条件式で「もし変数aが1と等しいなら」と書きたいとき、正しくはif (a == 1)
ですが、うっかりif (a = 1)
と書いてしまうことがあります。a = 1
は「aに1を代入する」という処理で、この代入処理自体が「成功した」という意味で多くの場合「真」と評価されてしまいます。結果、a
の値に関わらずif
文の中身が実行されてしまう、というバグにつながります。条件式での比較は必ず
==
を使う! と肝に銘じておきましょう。int a = 5; // これは間違い! aに1が代入され、条件は常に真になる if (a = 1) { printf("aは1です (間違い)\n"); // aが5でも表示されてしまう! } // 正しい比較 if (a == 1) { printf("aは1です (正しい)\n"); // aが5なので表示されない }
switch
文のbreak;
を忘れない!
先ほども触れましたが、switch
文の各case
の終わりにbreak;
を書き忘れると、処理が下のcase
に「突き抜けて」(フォールスルー)実行されてしまいます。意図的にフォールスルーを使う高度なテクニックもありますが、基本的にはバグの原因になるので、各case
の処理が終わったらbreak;
を書く、と覚えておきましょう。default:
の後にも念のため書いておくのが安全です。else if
の条件の順番に気をつける
else if
は上から順番に評価されます。例えば点数で成績を判定するとき、if (score >= 60) { printf("合格"); } else if (score >= 80) { printf("優秀"); }
と書いてしまうと、90点を取ったとしても最初の
if (score >= 60)
が真になってしまうため、「合格」と表示され、次のelse if (score >= 80)
は評価されません。「優秀」と表示させたいのに!複数の範囲を扱う場合は、より限定的な条件(狭い範囲)から先に書くか、条件の範囲が重ならないように注意深く設計する必要があります。
// 悪い例: 80点以上でも "合格" になってしまう if (score >= 60) { printf("合格\n"); } else if (score >= 80) { printf("優秀\n"); } // 良い例: 限定的な条件を先に書く if (score >= 80) { printf("優秀\n"); } else if (score >= 60) { printf("合格\n"); }
浮動小数点数(float
やdouble
)の比較は慎重に
コンピュータは小数を完全な精度で表現できない場合があります。そのため、if (f == 0.1)
のような、float
型やdouble
型の変数が特定の値と「完全に一致するか」を調べる比較は、予期せぬ結果になることがあります。例えば
0.1 + 0.2
が 0.3
と完全に一致しない、といったことが起こりえます。浮動小数点数を比較する場合は、完全に一致するかどうかではなく、差が非常に小さいかどうか(例:
fabs(f - 0.1) < 0.00001
のように絶対値の差を見る)で判定するのが一般的です。ちょっと難しい話ですが、頭の片隅に置いておくと良いでしょう。これらの注意点を意識して、バグの少ない、意図した通りに動くプログラムを目指しましょう!
【まとめ】C言語の条件分岐をマスターしてプログラムを操ろう!
お疲れ様でした! 今回はC言語の条件分岐、if
文とswitch
文について、基本的な書き方から実践的な使い方、そして注意点まで一通り見てきました。
もう一度ポイントをおさらいしましょう。
- 条件分岐は、プログラムの流れを状況に応じて変えるための仕組み。
if
文は「もし〜なら実行する」の基本。else
で「そうでなければ」の処理、else if
で複数の条件を追加できる。switch
文は、特定の値と一致するかで分岐させたいときに便利。case
とbreak;
のセットが基本。- 条件分岐は入れ子(ネスト)にできるけど、深くしすぎると読みにくくなるので注意。インデントは必須!
==
と=
の混同、break;
忘れなど、よくあるミスに気をつける。
条件分岐を使いこなせるようになると、書けるプログラムの幅がぐーんと広がります。最初は少し難しく感じるかもしれませんが、この記事のサンプルコードを実際に自分で打ち込んで、動かしてみるのが一番の近道です。
ぜひ、色々な条件で試してみて、「こう書くとこう動くのか!」という感覚を掴んでください。自信を持って、C言語の条件分岐を使いこなしていきましょう!
【関連記事】
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。