🖥️

【C言語超入門】 第09回 条件分岐

に公開

https://youtu.be/iEpNXMtr8uo

四国めたん
\textcolor{pink}{四国めたん: }教師役ですわ

ずんだもん
\textcolor{lime}{ずんだもん: }生徒役なのだ

\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです

\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ

\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう

\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ

\footnotesize \textcolor{pink}{四国めたん:} 第9回の今回は 条件分岐 についてお話ししますわ

\footnotesize \textcolor{lime}{ずんだもん:} お願いなのだ

条件分岐とは?

\footnotesize \textcolor{pink}{四国めたん:} 条件分岐 は真偽値を用いて実行するプログラムの流れを変更する機能でプログラミングの基本の1つですわ

\footnotesize \textcolor{lime}{ずんだもん:} プログラミングの基本?

\footnotesize \textcolor{pink}{四国めたん:} 以前にもお話ししましたがプログラミングの基本は3つですわ

  • 順次処理
  • 分岐
  • 反復

\footnotesize \textcolor{lime}{ずんだもん:} 順次処理分岐反復 だったかな?

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} 今までは 順次処理 のみを行ってきましたが以降は 条件分岐 も使っていきますわ

\footnotesize \textcolor{lime}{ずんだもん:} 分岐 ではなく 条件分岐 なのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、 分岐 には 条件分岐無条件分岐 の2種類がありますわ

\footnotesize \textcolor{pink}{四国めたん:} 今回は 条件分岐 についてのみですわね

\footnotesize \textcolor{lime}{ずんだもん:} 無条件分岐 は使わないのか?

\footnotesize \textcolor{pink}{四国めたん:} 実は 無条件分岐 は、ほぼ全てのプログラミング言語で使うことができますわ

\footnotesize \textcolor{pink}{四国めたん:} ただ一般的には 無条件分岐 の使用は非推奨、というより禁止に近いですわね

\footnotesize \textcolor{lime}{ずんだもん:} では 無条件分岐 についてはいったん置いておくのだ

\footnotesize \textcolor{pink}{四国めたん:} いえ、置いておくより、忘れて下さいね

条件分岐の基礎はif~else文ですよ

\footnotesize \textcolor{pink}{四国めたん:} では 条件分岐 について説明して行きますわね

\footnotesize \textcolor{pink}{四国めたん:} 先ずはプログラムを見てみましょう

#include <conio.h>
#include <stdio.h>

void main() {
  int c = 0;
  printf("キーボードから1文字、入力して下さい\n");
  c = _getch();

  if (c == 'a') {
    printf("キーボードからaが入力されました\n");
  } else {
    printf("キーボードからa以外が入力されました\n");
  }
}

コンソール画面

\footnotesize \textcolor{lime}{ずんだもん:} 「キーボードから1文字、入力して下さい」と表示されたのだ

\footnotesize \textcolor{pink}{四国めたん:} とりあえず\fcolorbox{blue}{lightgray}{a}を押してみましょう

\footnotesize \textcolor{lime}{ずんだもん:} 「キーボードからaが入力されました」と表示されたのだ

キーボード入力a

プログラムの解説です

\footnotesize \textcolor{pink}{四国めたん:} それではプログラムの解説を始めますわね

\footnotesize \textcolor{lime}{ずんだもん:} お願いするのだ

\footnotesize \textcolor{pink}{四国めたん:} まずプログラムではifというキーワードの後のカッコ内に 比較演算子 を使った式を記述していますわ

\footnotesize \textcolor{pink}{四国めたん:} もしカッコ内の式がtrueの場合には、続く中括弧"{}"内のプログラムが実行されますわ

\footnotesize \textcolor{lime}{ずんだもん:} プログラムではprintf("キーボードからaが入力されました¥n");の部分が実行されるのだ

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} もしカッコ内の式がfalseの場合には、elseに続く中括弧"{}"内のプログラムが実行されますわ

\footnotesize \textcolor{lime}{ずんだもん:} プログラムではprintf("キーボードからa以外が入力されました¥n");が実行されるのだ

\footnotesize \textcolor{pink}{四国めたん:} では試しにifの行にブレークポイントをセットし実行してみましょう

\footnotesize \textcolor{pink}{四国めたん:} キーボードからの入力は"a"としますわね

ブレークポイント入力a

\footnotesize \textcolor{lime}{ずんだもん:} 変数"c"の値に97という値が入っているのだ

\footnotesize \textcolor{pink}{四国めたん:} ここでif (c == 'a')の行の a の部分にカーソルを載せてみましょう

\footnotesize \textcolor{lime}{ずんだもん:} a の値が97であることが表示されるのだ

aのカーソル

\footnotesize \textcolor{pink}{四国めたん:} はい、結果として括弧内の式c == 'a'trueとなりますわね

\footnotesize \textcolor{pink}{四国めたん:} プログラムを再実行して、今度はキーボードから"b"を入力してみましょう

ブレークポイント入力b

\footnotesize \textcolor{lime}{ずんだもん:} こんどは変数"c"の値に98という値が入っているのだ

\footnotesize \textcolor{pink}{四国めたん:} 結果として括弧内の式c == 'a'falseとなりますわね

\footnotesize \textcolor{pink}{四国めたん:} プログラムを続行すると「キーボードからa以外が入力されました」と表示されるはずですわ

キーボード入力b

ifのみでelseがない?

\footnotesize \textcolor{pink}{四国めたん:} 次にelse以下がない場合を試してみましょう

#include <conio.h>
#include <stdio.h>

void main() {
  int c = 0;
  printf("キーボードから1文字、入力して下さい\n");
  c = _getch();

  if (c == 'a') {
    printf("キーボードからaが入力されました\n");
  }

  printf("プログラムを終了します\n");
}

\footnotesize \textcolor{pink}{四国めたん:} とりあえず実行してキーボードから"a"を入力してみますわ

キーボード入力a

\footnotesize \textcolor{lime}{ずんだもん:} 「キーボードからaが入力されました」、「プログラムを終了します」と表示されたのだ

\footnotesize \textcolor{pink}{四国めたん:} 次に再実行してから"b"を入力してみましょう

キーボード入力b

\footnotesize \textcolor{lime}{ずんだもん:} 単に「プログラムを終了します」とだけ表示されたのだ

\footnotesize \textcolor{pink}{四国めたん:} else以下がないので、式の評価がfalseの場合には何もせず、そのまま次のコードが実行されたのですわ

if~elseを重ねます

実はif~else文は重ねて使うことで 場合分け を行えます

例を見てみましょう

#include <stdio.h>
#include <conio.h>

void main() {
  int c = 0;
  printf("キーボードから1文字、入力して下さい\n");
  c = _getch();

  if (c == 'a') {
    printf("キーボードからaが入力されました\n");
  } else if (c == 'b') {
    printf("キーボードからbが入力されました\n");
  } else if (c == 'c') {
    printf("キーボードからcが入力されました\n");
  } else {
    printf("キーボードからa-c以外が入力されました\n");
  }
}

if~else文にelse ifを使用した行が増えています

これによりキーボードからの入力を"a"だけではなく"b"や"c"だった場合の処理も追加できています

つまり 場合分け ができています

当然ですがelse ifの部分を追加することで、さらに 場合分け を増やすことができます

ちなみに同じように 場合分け を行うためのswitch~case~default文というものがあります

条件分岐無条件分岐 の合わせ技のような感じです

結構複雑な上に、殆どの場合にif~else if~else文で代替可能なので C言語超入門 では扱いません

よくある間違い

\footnotesize \textcolor{pink}{四国めたん:} ところで 条件分岐 あるあるなのですがお聞きになります?

\footnotesize \textcolor{lime}{ずんだもん:} 聞きたいのだ!

\footnotesize \textcolor{pink}{四国めたん:} しかたないですわね

==です、=ではありませんよ

\footnotesize \textcolor{pink}{四国めたん:} 評価の式で比較演算を行う際には例えばイコール記号を2つ重ねて==としますわね

\footnotesize \textcolor{lime}{ずんだもん:} たしかにそうするように教わったのだ

\footnotesize \textcolor{pink}{四国めたん:} ところがイコール記号を1つだけ使って=としてしまう間違いが結構多いのですわ

\footnotesize \textcolor{lime}{ずんだもん:} 比較の代わりに代入を使ってしまうのか?

\footnotesize \textcolor{pink}{四国めたん:} ええ、似ているので間違えてしまうのでしょうね

\footnotesize \textcolor{pink}{四国めたん:} 間違っていてもエラーもワーニングも出ない場合が多いので注意が必要ですわ

\footnotesize \textcolor{lime}{ずんだもん:} 教えてくれないのか?

\footnotesize \textcolor{pink}{四国めたん:} 試してみましょう

#include <conio.h>
#include <stdio.h>

void main() {
  int c = 0;
  printf("キーボードから1文字、入力して下さい\n");
  c = _getch();

  if (c = 'a') {
    printf("キーボードからaが入力されました\n");
  }

  printf("プログラムを終了します\n");
}

=を使った実験

\footnotesize \textcolor{lime}{ずんだもん:} 確かにエラーもワーニングも出ないで普通に実行できてしまったのだ

\footnotesize \textcolor{pink}{四国めたん:} 試しに"b"を入力してみましょう

bを入力した結果

\footnotesize \textcolor{lime}{ずんだもん:} 「キーボードからaが入力されました」、「プログラムを終了します」と表示されたのだ

\footnotesize \textcolor{pink}{四国めたん:} printf("キーボードからaが入力されました¥n");の行にブレークポイントをセットして再実行してみましょう

\footnotesize \textcolor{pink}{四国めたん:} キーボードからは"b"を入力しますわ

bを入力した後のブレークポイント

\footnotesize \textcolor{lime}{ずんだもん:} 変数"c"の値を確認するとb(98)ではなくa(97)になっているのだ

\footnotesize \textcolor{pink}{四国めたん:} if (c = 'a')の部分で変数"c"に a (97)を代入しているのですから、当然ですわね

\footnotesize \textcolor{pink}{四国めたん:} で、c = 'a'の式の戻り値は 代入された値 と決められているので97が返ります

\footnotesize \textcolor{lime}{ずんだもん:} 戻り値が0以外だからtrueが返ったと判断されるのか?

\footnotesize \textcolor{pink}{四国めたん:} そうなりますわね

\footnotesize \textcolor{lime}{ずんだもん:} 対策はないのか?

\footnotesize \textcolor{pink}{四国めたん:} コンパイラによってはワーニングを出してくれる場合もありますが、期待はできませんわね

\footnotesize \textcolor{pink}{四国めたん:} ただ比較の際にa等の定数を先にするとエラーを出してくれますわ

#include <conio.h>
#include <stdio.h>

void main() {
  int c = 0;
  printf("キーボードから1文字入力して下さい\n");
  c = _getch();

  if ('a' = c) {
    printf("キーボードからaが入力されました\n");
  }

  printf("プログラムを終了します\n");
}

=を使ってエラー

\footnotesize \textcolor{lime}{ずんだもん:} 確かにエラーが出ているのだ

ifでnの範囲チェックは数学とは違うのですよ

\footnotesize \textcolor{pink}{四国めたん:} もうひとつ、間違いが多いif文についてお話ししますわね

\footnotesize \textcolor{lime}{ずんだもん:} おねがいするのだ

\footnotesize \textcolor{pink}{四国めたん:} int型 の変数"a"が0~10の範囲にあるかどうかをチェックする場合にはどのようにすれば良いでしょうか?

\footnotesize \textcolor{lime}{ずんだもん:} 数学では「もし0≦a≦10なら...」などと書けばいいのではないのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} でもC言語では少し違いますわ

\footnotesize \textcolor{pink}{四国めたん:} とりあえずはサンプルコードを見てみましょう

#include <stdio.h>

void main() {
  int c = 11;

  if ((0 <= c) && (c <= 10)) {
    printf("cは0~10の範囲です\n");
  } else {
    printf("cは0~10の範囲外です\n");
  }
}

範囲チェック

\footnotesize \textcolor{lime}{ずんだもん:} ちゃんと「cは0~10の範囲外です」と表示されたのだ

\footnotesize \textcolor{pink}{四国めたん:} サンプルコードの説明をしますわね

\footnotesize \textcolor{lime}{ずんだもん:} ifの条件が0 <= c <= 10とはなっていないのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、0 <= cc <= 10の2つの比較をAND&&演算子で繋いだ形になっていますわ

\footnotesize \textcolor{lime}{ずんだもん:} 0 <= c <= 10ではダメなのか?

\footnotesize \textcolor{pink}{四国めたん:} そうしたくなる気持ちは判りますが、C言語では正しく計算されません

\footnotesize \textcolor{pink}{四国めたん:} サンプルコードの場合、0 <= ctruec <= 10falseとなりますわ

\footnotesize \textcolor{lime}{ずんだもん:} 論理積をとれば、結果はfalseとなるのだ

\footnotesize \textcolor{pink}{四国めたん:} でも0 <= c <= 10とした場合は0 <= ctrueつまり、0以外の値となりますわ

\footnotesize \textcolor{pink}{四国めたん:} そして、次の<= 10truefalseのどちらにもなりえますわね

\footnotesize \textcolor{lime}{ずんだもん:} 結果がコンパイラやシステムによって異なるのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} まぁ、一般的にはtrueは1になる場合が多いので1 <= 10となってtrueが返りますわね

\footnotesize \textcolor{lime}{ずんだもん:} つまり結果が期待していたものと異なってしまうのだ

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} バグの元となるので、絶対に避けて下さいね

まとめ

\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした

\footnotesize \textcolor{pink}{四国めたん:} 以上で 条件分岐 を終了しますわ

\footnotesize \textcolor{lime}{ずんだもん:} おつかれさまなのだ

Discussion