プログラミング

C++超入門③ if文で条件によって処理を変えよう

if、else if、else、比較演算子、論理演算子、switch文を使い、条件によって動きが変わるプログラムを作ります。

点数が75なら合格、55なら復習。入力や値によって動きを変えたいときに使うのが条件分岐です。

ifの形だけなら短いのですが、順番や境目を間違えると、動いているのに結果がおかしくなります。今回は「なぜその分岐に入るのか」を、値を変えながら確認しましょう。

短いコードは#include <iostream>があるプログラムのmain内で試します。変数と入力は前回で扱いました。

1. 条件がtrueなら、その中を実行する

#include <iostream>

int main() {
    int score = 75;

    if (score >= 60) {
        std::cout << "合格です。\n";
    }

    std::cout << "判定を終えました。\n";
    return 0;
}

表示は「合格です」「判定を終えました」の2行です。

score >= 60は「scoreが60以上か」という比較です。成り立てばtrue、成り立たなければfalseという真偽値になります。

scoreを55に変えると、ifの中は飛ばされます。ただし最後の表示は波かっこの外なので、引き続き実行されます。

ifの範囲を決めるのは字下げではなく{ }です。中身が1行でもかっこを省かない方が、後で行を増やすときに間違えにくくなります。

2. elseは「そうでなければ」

int score = 55;

if (score >= 60) {
    std::cout << "合格です。\n";
} else {
    std::cout << "もう一度復習しましょう。\n";
}

どちらか片方だけが実行されます。最後のelseには条件を付けません。最初の条件に当てはまらなかったすべての場合を担当します。

ここで大切なのは、「elseに進んだとき、何が分かっているか」です。今回なら、すでにscore >= 60が偽なので、60未満だと分かっています。

3. else ifの順番で、結果が変わる

int score = 85;

if (score >= 80) {
    std::cout << "とてもよくできました。\n";
} else if (score >= 60) {
    std::cout << "合格です。\n";
} else {
    std::cout << "復習しましょう。\n";
}

85は80以上なので、最初の表示だけで終わります。後ろのscore >= 60も数学的には真ですが、そこまで調べません。

点数 最初の比較 次の比較 表示
85 真 調べない とてもよくできました
75 偽 真 合格
55 偽 偽 復習

80以上より先に60以上を置くと、85が「合格」に入ってしまいます。一度選んだら後ろへ進まないことを意識して順番を決めます。

ifを2つ並べる場合

独立したif (score >= 80)とif (score >= 60)を続けると、85では両方実行されます。

1つの評価を選びたいなら連続したelse if、当てはまる処理をそれぞれ追加したいなら独立したifです。C++公開標準草案のif文でも、この分岐の関係を確認できます。

4. 比較の記号は「境目を含むか」で覚える

記号 意味
== 等しい
!= 等しくない
> より大きい。境目を含まない
< より小さい。境目を含まない
>= 以上。境目を含む
<= 以下。境目を含む

score > 60なら60点は含まれません。60点を合格にしたい場合は>=です。

=は代入、==は比較です。if (score = 60)はscoreを60へ変更してしまい、0以外なので真になります。コンパイルできても意図と違う場合があるため、警告も確認しましょう。

また、if (score >= 60);の余分なセミコロンも注意点です。条件に対応する処理が「何もしない文」になり、その後のまとまりが条件と無関係に動く原因になります。

5. &&・||・!を使う

int age = 19;
bool hasTicket = true;

if (age >= 18 && hasTicket) {
    std::cout << "入場できます。\n";
}

&&は「かつ」です。18歳以上であることと、チケットを持つことの両方を満たす必要があります。

||は「または」、!は真偽を反対にします。ここで使う&&や||は論理演算子で、&や|を1つだけ書く演算とは別です。

0から100の範囲は2つの比較にする

if (score >= 0 && score <= 100) {
    std::cout << "有効な点数です。\n";
}

0 <= score <= 100とは書きません。C++では左側の比較結果trueまたはfalseを、さらに100と比較する形になるため、期待する範囲判定になりません。

範囲外を調べるなら、score < 0 || score > 100です。「内側はかつ、外側はまたは」と図を思い浮かべると、最初は分かりやすいでしょう。

危険な処理の前に確認する

int total = 10;
int count = 0;

if (count != 0 && total / count >= 2) {
    std::cout << "平均は2以上です。\n";
}

&&は左が偽なら右を実行しません。この短絡評価で、0除算へ進む前に止められます。逆の順番だと先に割ってしまうので、順番も処理の一部です。

6. 入力の確認と、評価の判定を分ける

#include <iostream>

int main() {
    int score = 0;
    std::cout << "点数(0-100): ";

    if (!(std::cin >> score)) {
        std::cout << "整数として読めませんでした。\n";
        return 1;
    }
    if (score < 0 || score > 100) {
        std::cout << "0から100の範囲で入力してください。\n";
        return 1;
    }

    if (score >= 80) {
        std::cout << "とてもよくできました。\n";
    } else if (score >= 60) {
        std::cout << "合格です。\n";
    } else {
        std::cout << "復習しましょう。\n";
    }
    return 0;
}

-5や200を、そのまま成績として判定しないようにしています。先に「扱ってよい値か」、その後で「どう評価するか」を分けると、複雑な条件を1つへ詰め込まずに済みます。

このcinは先頭の数値部分を読む方法です。80点など行全体を拒否したい場合は、最終回の入力方法を使います。

7. switchは決まった選択肢に向いている

int menu = 2;

switch (menu) {
    case 1:
        std::cout << "ゲームを開始します。\n";
        break;
    case 2:
        std::cout << "設定を開きます。\n";
        break;
    default:
        std::cout << "1か2を選んでください。\n";
        break;
}

menuと一致するcaseへ進み、breakで抜けます。どれにも当てはまらない場合がdefaultです。

breakを忘れると、次のcaseの処理も続けて実行するフォールスルーが起きます。範囲の比較はif、メニュー番号や列挙型はswitch、という使い分けが最初は分かりやすいでしょう。std::stringをそのままswitchの対象にはできません。

8. 練習:年齢で料金区分を表示しよう

今回は架空の料金ルールです。0〜120歳の整数について、12歳以下を子ども、13〜64歳を通常、65歳以上をシニアと表示します。

模範解答

#include <iostream>

int main() {
    int age = 0;
    std::cout << "年齢(0-120): ";

    if (!(std::cin >> age) || age < 0 || age > 120) {
        std::cout << "入力を確認してください。\n";
        return 1;
    }

    if (age <= 12) {
        std::cout << "子ども料金\n";
    } else if (age >= 65) {
        std::cout << "シニア料金\n";
    } else {
        std::cout << "通常料金\n";
    }
    return 0;
}

解説

入力を確認してから、12歳以下か、65歳以上かを調べます。その両方ではない値が13〜64歳なので、最後のelseで通常料金になります。

確認用の答えは、12→子ども、13→通常、64→通常、65→シニアです。境目とそのすぐ隣を試すと、<と<=の間違いが見つかりやすくなります。

シニアの条件を先に置く書き方でも、この2つの範囲は重ならないため同じ結果になります。

次の一歩

条件を作る前に、代表的な入力と期待する結果を並べてみましょう。文章で決めたルールを、そのまま比較と分岐へ落とし込む感覚が大切です。

前の記事 / 次の記事:繰り返し

← 記事一覧へ戻る