注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。
C言語では論理値の扱い方に要注意である。C言語では厳密には論理型はなく、実際には整数値であたかも論理型を表現しているからである。
C言語で論理型の条件分岐をするときの注意点
C言語では以下のような論理型の書き方はしてはならない
1 2 |
if ( XXX == TRUE ) |
これは、C言語特有の問題で、コードによっては問題を引き起こす場合があるからである。というのは、C言語では論理値の比較は0かどうかで比較しているからである1 。したがって、それを念頭に入れないと問題を引き起こすことがある。
問題を引き起こさない例
例えば、以下のコードは問題は顕在化しない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <stdio.h> #include <stdbool.h> _Bool is_equal(int val1, int val2); int main(void) { if (is_equal(1, 1) == true) { puts("equal"); }else{ puts("not equal"); } return 0; } _Bool is_equal(int val1, int val2) { if (val1 == val2) { return true; } else { return false; } } |
上記の場合、is_equal
という関数において、明確にfalseかtrueかを返しているため、問題とならない。
問題を引き起こす例
以下の場合は、問題を引き起こす。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <stdio.h> int is_differ(int val1, int val2); int main(void) { if (is_differ(1, 3) == true) { puts("differ"); }else{ puts("not differ"); } return 0; } int is_differ(int val1, int val2) { return val1 - val2; } |
この場合、本来であれば「differ」が出力されることを期待するが、実際には「not differ」が出力されてしまう。これは、C言語に詳しい開発者の一部は「C言語の論理値の比較は0かそれ以外で行う」ことを知っているため、そのために「0か1である必要がない」と考えることがあるからである。
それを知らないと認識の問題が発生して、問題となる。
対策法
上記の場合はif (is_differ(1, 3) == true)
をif (is_differ(1, 3))`にすれば良い。そうすれば、0以外はtrueとして扱われるため、想定通りの動作になる。
最後に
C言語の論理値の条件分岐は0かどうかで行われるので、それを知らないと思わぬ問題に遭遇してしまうことがある。
そのため、もし、if ( XXX == TRUE )
というような書き方をしていたら、即座にif ( XXX )
とするようにしよう。if ( XXX == FALSE )
はFALSEが0ということは明らかなので問題ないが、整合性を考えるとif ( !XXX )
としても良いだろう。

ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しています。ご用の方はコメントかコンタクトフォームにて。
- 0であればfalse、それ以外であればtrue [↩]