https://youtu.be/8OoqNNgXd7c
\textcolor{pink}{四国めたん: } 教師役ですわ
\textcolor{lime}{ずんだもん: } 生徒役なのだ
\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです
\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう
\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ
\footnotesize \textcolor{pink}{四国めたん:} 第8回の今回は 真偽値型と比較演算 についてお話ししますわ
\footnotesize \textcolor{lime}{ずんだもん:} 真偽値型?
\footnotesize \textcolor{pink}{四国めたん:} はい、boolean型やbool型とも言いますわ
\footnotesize \textcolor{lime}{ずんだもん:} 整数型や浮動小数点数型とは違うのか?
\footnotesize \textcolor{pink}{四国めたん:} 整数型や浮動小数点数型は様々な値を取ることができますわ
\footnotesize \textcolor{pink}{四国めたん:} でも 真偽値型 はtrue
とfalse
の2つの値のみを取ることができるのですわ
\footnotesize \textcolor{lime}{ずんだもん:} たった2つの値とはビックリなのだ
真偽値を使ってみました
\footnotesize \textcolor{pink}{四国めたん:} 実際に使ってみましょう
#include <stdio.h>
#include <stdbool.h>
void main()
{
bool t = true;
bool s = false;
printf("真偽値を使ってみました。");
}
\footnotesize \textcolor{pink}{四国めたん:} printf
の行にブレークポイントをセットして実行してみますわ
\footnotesize \textcolor{lime}{ずんだもん:} 変数"t"にはtrue
が、変数"s"にはfalse
が代入されているのだ
真偽値を使うにはヘッダーが必要です
\footnotesize \textcolor{pink}{四国めたん:} では、それぞれの行について説明していきますわね
\footnotesize \textcolor{lime}{ずんだもん:} よろしくなのだ
\footnotesize \textcolor{pink}{四国めたん:} まず#include <stdbool.h>
により"stdbool.h"と云うファイルを読み込みますわ
\footnotesize \textcolor{lime}{ずんだもん:} "stdbool.h"とはどういったファイルなのだ?
\footnotesize \textcolor{pink}{四国めたん:} 真偽値型で使用するbool
やtrue
、false
等について定義しているファイルですわね
\footnotesize \textcolor{pink}{四国めたん:} 読み込んでおかないとbool
やtrue
、false
がエラーになりますわ
\footnotesize \textcolor{lime}{ずんだもん:} "stdbool.h"の中身はどうなっているのだ?
\footnotesize \textcolor{pink}{四国めたん:} たいしたことは書かれていませんが、気にする必要はありませんわね
\footnotesize \textcolor{pink}{四国めたん:} 次に真偽値型の変数はbool
として宣言しますわ
\footnotesize \textcolor{pink}{四国めたん:} そしてtrue
およびfalse
と云う値で初期化しますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
真偽値を表示するには…
\footnotesize \textcolor{lime}{ずんだもん:} ところで、なぜprintf
で"t"や"s"の値を表示しないのだ?
\footnotesize \textcolor{pink}{四国めたん:} 実はですね…、C言語のprintf
には今のところ真偽値型をそのまま表示できる 書式指定子 が存在しないのですわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} ですので真偽値をprintf
で表示したい場合には整数値として表示しますわ
\footnotesize \textcolor{pink}{四国めたん:} とりあえず試してみましょう
#include <stdio.h>
#include <stdbool.h>
void main()
{
bool t = true;
bool s = false;
printf("真は%d、偽は%dです。", t, s);
}
\footnotesize \textcolor{pink}{四国めたん:} ブレークポイントを外して実行してみますわね
\footnotesize \textcolor{lime}{ずんだもん:} 真 もしくはtrue
は1、 偽 もしくはfalse
は0となったのだ
\footnotesize \textcolor{pink}{四国めたん:} もともとC言語には真偽値型は存在せず、整数型で代用しているのですわ
\footnotesize \textcolor{pink}{四国めたん:} そのため0は 偽 を、0以外は 真 と決めていましたわ
\footnotesize \textcolor{lime}{ずんだもん:} 0と0以外?
\footnotesize \textcolor{pink}{四国めたん:} はい、大事なのでもう一度言いますが、0以外が 真 ですわ
\footnotesize \textcolor{pink}{四国めたん:} 1でも2でも100や-1であっても 真 と判断されますわね
\footnotesize \textcolor{lime}{ずんだもん:} けっこういい加減なのだ
\footnotesize \textcolor{pink}{四国めたん:} 意外と間違う場合が多いので気をつけて下さいね
\footnotesize \textcolor{pink}{四国めたん:} なお標準で真偽値型を定義する言語が増えて来たので最近ではC言語でも真偽値型が使えるようになりましたわ
\footnotesize \textcolor{pink}{四国めたん:} 将来的には"stdbool.h"を読み込まなくても真偽値型が使えるようになりますわね
\footnotesize \textcolor{lime}{ずんだもん:} 楽しみなのだ
真偽値型
C23から真偽値型がデフォルトで使用できるようになり、"stdbool.h"をインクルードする必要が無くなるかも知れません
それに伴いbool
, false
, true
がキーワードとして登録されるようです
C23は2024年6月時点でリリースされてはいませんが、略決まりでしょう
ただC23がリリースされて"stdbool.h"をインクルードする必要が無くなっても"stdbool.h"は残ると思います
特に意味が無くても、後方互換のために残されるはずです
なので現状でbool
やfalse
, true
を使用する場合には、安心して"stdbool.h"をインクルードしましょう
真偽値の演算は可能ですか?
\footnotesize \textcolor{lime}{ずんだもん:} ところで真偽値型を整数型で代用していたのなら真偽値型に四則演算を行うことはできるのか?
\footnotesize \textcolor{pink}{四国めたん:} 可能ですわ
\footnotesize \textcolor{pink}{四国めたん:} でも意味がありませんわね
\footnotesize \textcolor{lime}{ずんだもん:} たしかに真偽値の足し算や引き算なんて聞いた事がないのだ
論理演算を使いましょう
\footnotesize \textcolor{pink}{四国めたん:} 一般的には真偽値には 論理演算 を用いますわ
\footnotesize \textcolor{lime}{ずんだもん:} 論理演算?
\footnotesize \textcolor{pink}{四国めたん:} はい、 論理積 (AND)や 論理和 (OR)、 否定 (NOT)などですわね
\footnotesize \textcolor{pink}{四国めたん:} まず 論理積 ですが、演算子はアンパサンドを2つ重ねた形&&
ですわ
\footnotesize \textcolor{pink}{四国めたん:} a && b
で、aとbが共に真の時に真が返りますわ
\footnotesize \textcolor{lime}{ずんだもん:} どちらかが偽の時は、偽が返るのか
\footnotesize \textcolor{pink}{四国めたん:} 次に 論理和 ですが、演算子は縦棒を2つ重ねた形||
ですわ
\footnotesize \textcolor{pink}{四国めたん:} a || b
で、aかbの少なくとも一方が真の時に真が返りますわ
\footnotesize \textcolor{lime}{ずんだもん:} どちらもが偽の時のみ、偽がかえるのか
\footnotesize \textcolor{pink}{四国めたん:} 最後に 否定 ですが、演算子は感嘆符!
ですわ
\footnotesize \textcolor{pink}{四国めたん:} !a
で、aが真の時に、偽が返りますわ
\footnotesize \textcolor{lime}{ずんだもん:} aが偽の時に真が返るのか
真偽値の演算子
演算子
名前
例
意味
&&
論理積 AND
a && b
aとbが共に真の時に真が返る
||
論理和 OR
a || b
aかbの少なくとも一方が真の時に真が返る
!
否定 NOT
!a
aが真の時に偽が、偽の時には真が返る
\footnotesize \textcolor{pink}{四国めたん:} とりあえずプログラムを書いて実行してみましょう
#include <stdio.h>
#include <stdbool.h>
void main()
{
bool a = true;
bool b = false;
bool t = (a && b);
bool s = (a || b);
bool u = !a;
printf("a && bは%dです。\n", t);
printf("a || bは%dです。\n", s);
printf("!aは%dです。\n", u);
}
\footnotesize \textcolor{pink}{四国めたん:} 結果は「a && bは0です。」、「a || bは1です。」、「!aは0です。」となりますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{lime}{ずんだもん:} ところで倫理積と論理和の演算子の&
と|
が2つ重なっているのには意味があるのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、&
や|
が1つの演算子は別の演算子なので間違わない様にしましょう
\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ
比較演算を使ってみましょう
\footnotesize \textcolor{pink}{四国めたん:} 真偽値型に係わる演算は 論理演算 の他に 比較演算 がありますわ
\footnotesize \textcolor{lime}{ずんだもん:} 比較演算?
\footnotesize \textcolor{pink}{四国めたん:} はい、整数や浮動小数点数の大小を比較する演算子ですわね
\footnotesize \textcolor{lime}{ずんだもん:} なぜ真偽値型が係わるのだ?
\footnotesize \textcolor{pink}{四国めたん:} 演算結果が真偽値になるからですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} とりあえずプログラムを書いて実行してみましょう
#include <stdio.h>
#include <stdbool.h>
void main()
{
int a = 1;
int b = 2;
bool t = (a < b);
bool s = (a == b);
printf("a < bは%dです。\n", t);
printf("a == bは%dです。\n", s);
}
\footnotesize \textcolor{lime}{ずんだもん:} 「a < bは1です。」、「a == bは0です。」と表示されたのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、ここでは不等号<
や、等号が2つの==
が 比較演算子 となりますわ
\footnotesize \textcolor{pink}{四国めたん:} 意味としては「aはbより小さい」、「aとbは等しい」となりますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほど、結果としてa < b
は true (1)、a == b
は false (0)となったのだ
「代入」と「等しい」は異なります
\footnotesize \textcolor{pink}{四国めたん:} ここで注意して欲しいのは、 等しい を表す演算子が等号2つ==
だということですわ
\footnotesize \textcolor{pink}{四国めたん:} 代入 を表す=
と書き間違いをする場合が多いので注意が必要ですわ
\footnotesize \textcolor{lime}{ずんだもん:} 気をつけるのだ
\footnotesize \textcolor{pink}{四国めたん:} 最近のIDEは警告をしてくれる場合がありますが、文法的には間違いではないので警告もない場合が多いですわ
\footnotesize \textcolor{pink}{四国めたん:} ためしに==
の部分を=
に直してみましょう
#include <stdio.h>
#include <stdbool.h>
void main()
{
int a = 1;
int b = 2;
bool t = (a < b);
bool s = (a = b);
printf("a < bは%dです。\n", t);
printf("a = bは%dです。\n", s);
}
\footnotesize \textcolor{lime}{ずんだもん:} 何のエラーもなく実行できてしまっているのだ
\footnotesize \textcolor{pink}{四国めたん:} 出力が「a = bは1です」となっていて、明らかに意図していない結果となっていますわ
代入演算子について
!
上記サンプルコードでbool s = (a = b);
で"s"が1(true)になる仕組みについては以下の通りです
まず、C言語では代入"="を演算子として扱います
なので値を返します
返す値は、代入された値となります
上記サンプルコードでは"a"に"b"の値、2が代入されて、そのまま2が返ります
"s"には(a = b)
で返された値、2が代入されます
ところが"s"は真偽値型なので、2つまり0以外の値が代入された時点でtrue
がセットされます
そしてVisual Studioではtrue
を整数値として表示する際には1となりますので「a = bは1です」と表示されます
\footnotesize \textcolor{lime}{ずんだもん:} ところでa < b
やa == b
の部分を括弧で括っているのはなぜなのだ?
\footnotesize \textcolor{pink}{四国めたん:} 見やすくするためですわ
\footnotesize \textcolor{lime}{ずんだもん:} 確かに見やすいのは大事なのだ
s = a == bの演算の順番
サンプルコードではbool s = (a == b);
としていますがbool s = a == b;
と括弧を付けない場合はどうなるのでしょうか
以前の回で 演算子の優先順位 についてお話ししたのですが、==
は=
よりも優先順位が高いので、括弧を付けない場合でもa == b
が先に演算されます
ちなみにbool s = a = b;
の場合はどうでしょうか?
実は=
演算子は右にある演算子を優先して演算する決まりがありますので、a = b
が先に演算されます
\footnotesize \textcolor{pink}{四国めたん:} 比較演算子については<
や==
を含めて表に示したものがありますわ
比較演算子
演算子
例
意味
==
a == b
aとbは等しい
!=
a != b
aとbは等しくない
<
a < b
aはbより小さい
>
a > b
aはbより大きい
<=
a <= b
aはbより小さいか等しい
>=
a >= b
aはbより大きいか等しい
浮動小数点における比較はできますか?
\footnotesize \textcolor{pink}{四国めたん:} なお比較対象は数値であれば何でもOKですわ
\footnotesize \textcolor{pink}{四国めたん:} 整数以外、例えば浮動小数点数等では次のようになりますわ
#include <stdio.h>
#include <stdbool.h>
void main()
{
double a = 1.0;
double b = 2.0;
bool t = (a < b);
bool s = (a == b);
printf("a < bは%dです。\n", t);
printf("a == bは%dです。\n", s);
}
\footnotesize \textcolor{pink}{四国めたん:} 最後に比較演算における注意点を幾つか上げておきますわ
\footnotesize \textcolor{pink}{四国めたん:} まず浮動小数点数を含む比較演算で==
や!=
は推奨できませんわ
\footnotesize \textcolor{lime}{ずんだもん:} なぜなのだ?
\footnotesize \textcolor{pink}{四国めたん:} 簡単なプログラムでは問題になりませんが、複雑な計算を含むプログラムでは誤差により正確な答えが出ない場合が多いからですわ
\footnotesize \textcolor{lime}{ずんだもん:} 誤差がでると値が等しくなくなってしまうのだ
浮動小数点数の比較
!
浮動小数点数の比較として"=="や"!="を使用するとどうなるかを確認してみましょう
#include <stdio.h>
#include <stdbool.h>
void main() {
float x = 0.1;
bool s = (x == 0.1);
printf("xは0.1か? %d\n", s);
}
上記サンプルコードでは、本来"s"はtrue
になることを期待しますが、結果はfalse
となります
どうしても浮動小数点数で等しいかどうかを確認する必要がある場合には、2つの浮動小数点数の差分が許容範囲に収まっているかどうかで判断します
とりあえずはサンプルコードを見てみましょう
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
void main() {
float x = 0.1;
bool s = (abs(x - 0.1) < 0.0001);
printf("xは0.1か? %d\n", s);
}
abs
関数は"math.h"で宣言されていて、絶対値を返します
2つの浮動小数点数の差分が負数の場合に正数に修正します
今回は許容できる差分を0.0001としていますが、この値は状況により変える必要があります
\footnotesize \textcolor{pink}{四国めたん:} 次に真偽値型の比較演算は意味がないので使わない方が良いですわ
\footnotesize \textcolor{pink}{四国めたん:} 特にtrue
に対する比較演算は絶対に避けて下さいね
\footnotesize \textcolor{lime}{ずんだもん:} なぜなのだ?
\footnotesize \textcolor{pink}{四国めたん:} C言語では 偽 の値は0と決まっていますが、 真 の値は 0以外 の値なので、比較することができないからですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
まとめ
\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした
\footnotesize \textcolor{pink}{四国めたん:} 以上で 真偽値型と比較演算 を終了しますわ
\footnotesize \textcolor{lime}{ずんだもん:} おつかれさまなのだ
Discussion