Shunk

Shunk/C言語から学ぶ「条件分岐『if』」

Created Sat, 06 Jul 2024 10:33:59 +0900

初めに

今回はプログラムの三つの制御構造のうちのひとつ「分岐処理」を学んでいこう。

制御構文とは

制御構造について軽く触れておくと、全てのコードは、細かく細かく分解していくと3のことしかしていない。 順次処理、繰り返し処理、分岐処理の三つだ。

この三つを組み合わせて全てのプログラムが成り立っている。 (!!!)

例えば自動運転のような複雑な処理でも分解するとこの組み合わせなのだ。

どのような書き方なのか

以下のように書く。

if (条件分岐) {
    条件が成り立つときの処理A;
}

if (条件分岐)のところには色々なものを入れられる。

例を示そう

int a = 100;
if (a > 50) {
    printf("50より大きい");
}

これだと"50より大きい"が出力される。 仮に1行目をa = 10に変えてみると、何も出力されない。

算数の「>(大なり)」「<(小なり)」と同じなのでわかりやすいだろう a と 50を比べて aの方が大きかったので条件に適しているという判定になるのだ。

ここで出てきた**>**は関係演算子と呼ばれるものだ。 簡単なので覚えておこう。

演算子説明
==【左】と【右】の値が等しいかどうか
===【左】と【右】の値と型が等しいかどうか
!=【左】と【右】の値が等しくないかどうか
!==【左】と【右】の値または型が等しくないかどうか
<【左】の値が【右】の値よりも小さいかどうか
>【左】の値が【右】の値よりも大きいかどうか
<=【左】の値が【右】の値以下かどうか
>=【左】の値が【右】の値以上かどうか

コラム: 「!」と言う記号の意味

!と言う記号は、日常的には驚きを表現する記号だが、プログラムの世界では「否定」の意味がある(ことが多い)。

先ほどの演算子を見てみよう。 **「==」は左右が等しいと言う意味だが、「!=」**だと左右が等しくないと言う意味になる。

同じように **「===」は左右が型も含めて等しいと言う意味だが、「!==」**だと左右が型も含めて等しくないと言う意味になる。

このように「!」と言う記号が出てきたら否定の意味がありそうだなと思うようにしよう。

条件が成り立たないときにも何かをさせたい

以下のようにelseというものを追加して書くこともできる。

if (条件分岐) {
    条件が成り立つときの処理A;
} else {
    条件が成り立たないときの処理B;
}

この場合だと条件が成り立たないときにも、特定の処理を行わせることができる

先ほどの例だと

int a = 10;
if (a > 50) {
    printf("50より大きい");
} else {
    printf("50以下");
}

このコードを実行すると"50以下"が出力される。 逆に1行目で a = 100を代入すると、前回の例のように"50より大きい"が出力される。

条件に適していない場合でも何かしらの処理をさせたいときにはこの書き方を使おう。

条件が適さなかったときに別の条件分岐も入れたい

以下のように書くと、複数の条件で分岐を作ることができる。

if (条件分岐A) {
    条件Aが成り立つときの処理A;
} else if (条件分岐B) {
    条件Bが成り立つときの処理B;
} else {
    条件が一つも成り立たないときの処理C;
}

先ほどの例だと

int a = 20;
if (a > 50) {
    printf("50より大きい");
} else if (a > 10) {
    printf("10より大きい");
} else {
    printf("10以下");
}

これだと"10より大きい"が出力される。 大体わかってきただろう。

しかしここで注意しなくてはいけないことが一つある。 条件分岐の順番だ。

例えば以下のコードを書いたとする

int a = 100;
if (a > 10) {
    printf("10より大きい");
} else if (a > 50) {
    printf("50より大きい");
} else {
    printf("10以下)
}

これだとaは100なので"50より大きい"が出力されそうなものだが、実際には “10より大きい"が出力される。 この現象は条件分岐が上から実行されるという特性が原因で起きている。

最初に a > 10を確認して、その条件が当てはまっていたらその下の条件文は実行すらされないのだ。

複雑な条件を使いたい

今までの例はかなり単純な条件分岐だったが実際にコードを書く際にはこんなに単純じゃないこともある。

例えば、国語算数英語、全てのテストの点数が50点以上かどうかを判別したい場合を考えよう。 今まで説明した書き方だと以下のようなコードになってしまう。

int math = 50
int japanese = 53
int english = 30

if(math > 50) {
    if(japanese > 50) {
        if(english > 50) {
            printf("全てのテストが50点以上です");
        }
    }
}

これだとネストが深くてわかりづらい。

ネストとは

ネストとはコードの階層構造のことだ。

if (math>50) {
    処理A
}

上のコードを見ると処理Aが{}に囲われて、行の開始位置が少しだけ右にずれていることがわかる(インデントと呼ぶ)。 一つか二つなら問題がないが、複数の階層構造が存在すると読みづらくなるのでできるだけ避けるようにしよう。

複数の条件を一つの条件にまとめる書き方ができる。 以下のコードを見てみよう

int math = 50
int japanese = 53
int english = 30

if(math > 50 && japanese > 50 && english > 50) {
    printf("全てのテストが50点以上です");
}

だいぶすっきりとしたことがわかる。

ここでポイントなのが**&&という記号だ。 これは日本語で言うところのかつ**に対応するものだ。

つまり先ほどの条件は

if(数学が50点以上 かつ 国語が50点以上 かつ 英語が50点以上)

と言う意味になる。

この&&のような記号を論理演算子と呼ぶ。

これも単純なので覚えてしまおう。

演算子説明
&&「かつ」と同じ。【左】と【右】が両方正しいか確認する
`