読者です 読者をやめる 読者になる 読者になる

各言語におけるtrue/falseまとめ

たとえば PHP で、

if ($hoge) {
  ...
}

とか書いてあったら、 $hoge がどんな値のときに if の中身が実行されるのか即答できますか。
こういう書き方は多くの言語で可能ですが、言語によって何が真で何が偽になるのかが異なるので、それぞれまとめてみました。

C言語

C言語には bool 型が無い。

  • 0 (int)

だけが偽となり、それ以外はすべて真となる。
NULL 定数は stddef.h で以下のように ((void*)0) と定義されているため、偽値として使える。
意見が分かれそうなところですが、個人的にはNULLを偽値として使用するは好きじゃないです。

#ifndef __cplsuplus
#define NULL ((void*)0)
#else
#define NULL __null
#endif

C++

C++になると bool 型が出てくる。C と同様に、 0 が偽でそれ以外が真となるが、bool 型リテラル false は 0 として評価されるため、偽となる。

  • 0 (int)
  • false

が偽となり、それ以外が真となる。

Java

  • false

のみが偽となり、

  • true

のみが真となる。
Javaではこれら以外の値が真偽値に暗黙的に変換されたりはしない。

JavaScript (ECMA-262)

false(偽)になるものは下記のみ。

  • false
  • undefined
  • null
  • +0,-0,NaN
  • "" (空文字)

これら以外は真として扱われる。Objectは全部真になる。なので空配列なども真。

参考:
Standard ECMA-262 ECMAScript Language Specification 3rd edition (December 1999)

Ruby

Ruby はシンプル。

  • false
  • nil

の二つ以外はすべて真として扱われる。
Ruby の面白いのは、Boolean というクラスは無く、 true と false はそれぞれ TrueClass と FalseClass というクラスのインスタンスである。

参考:
library _builtin

PHP

PHP は複雑。以下のものが偽となり、これら以外はすべて真となる。
PHP: 論理型 (boolean) - Manualから抜粋)

  • boolean の FALSE
  • integer の 0 (ゼロ)
  • float の 0.0 (ゼロ)
  • 空の文字列、 および文字列の "0"
  • 要素の数がゼロである 配列
  • メンバ変数の数がゼロである オブジェクト (PHP 4のみ)
  • 特別な値 NULL (値がセットされていない変数を含む)
  • 空のタグから作成された SimpleXML オブジェクト

こんなに多かったら覚えられないなー。だからよっぽど自明なシーン以外は、みんなが読むようなコードに

if ($hoge) {
  ...
}

とか書くべきじゃない気がしますね。

参考:
PHP: 論理型 (boolean) - Manual

Perl

ラクダ本より。

  • ""と"0"を除き、すべての文字列は真である
  • 0を除き、すべての数値は真である
  • すべてのリファレンスは真である
  • すべての未定義値は偽である

だそうです。

Python

  • None
  • False
  • 数値型に置けるゼロ(e.x.: 0, 0L, 0.0, 0j)
  • 空のマッピング型(e.x.: {})
  • __nonzero__()または__len__()メソッドが定義されているクラスのインスタンスで、そのメソッドが(数値型の9ゼロまたはbool値のFalseを返す時

以上に当てはまらなければ全て真だそうですが、正直Pythonはよく知らないのでなんのこっちゃ分かりません。

追記(2009.06.05)
「みんなのPython」には下記のように書かれているそうです。thanks: noname

以下のような組み込み型オブジェクトをbool値として評価したときにTrueと評価。
・0以外の数値
・長さのある文字列(空でない文字列)
・要素を持つ、リストやタプルのようなシーケンス
・要素を持つ辞書
以下のような組み込み型オブジェクトをbool値として評価したときにFalseと評価。
・数値の0
・空の文字列(空の文字列は""で定義できる)
・空のリストやタプル(空のリストは[]で定義できる)
・空の辞書(空の辞書は{}で定義できる)
みんなのPythonより

参考:
KOSHIGOE学習帳 - [python]真偽値、比較、整数

早見表

以上を表にしてみた。

C C++ Java JS Ruby PHP Perl
true -*1 -
false - -
0(整数) ×
1(整数) ×
0.0(小数) (偽) (偽) ×
"0"(文字列) (真) (真) ×
NaN (真) (真) ×
空文字 (真) (真) ×
空配列 - - × *2
null/nil *3 *4 × ×
未定義値/undefined/undef - -

- ・・・言語仕様に存在しない
× ・・・言語仕様に存在するが真偽値として使用できない
(真)・・・真となるがいい方法ではない
(偽)・・・偽となるがいい方法ではない
不・・・不定

まとめ

まあこんな感じで、言語によって真偽値の事情は異なるので、 if 文では比較演算子などを省略しない方が安心ですね!!

追記(2009.06.05)

  • 早見表のNaNの行がいろいろ間違っていたので修正しました。 thanks: dankogai, id:lombriz, なまえ, id:t-tanaka
  • 早見表で、PHP の null を「×」と書いていましたが正しくは「偽」です。 thanks: id:kent013
  • Python についての補足を追記しました。 thanks: noname

追記(2009.06.06)

  • C言語での NULL の偽値としての使用について、記述を改めました。
  • C言語での「空配列」は「(偽)」から「-」に変更しました。 thanks: id:temtan

*1:C99には_Bool型があります。thanks id:uruloki

*2:リファレンスの場合

*3:stddef.hのNULLは ((void*) 0) なので

*4:C++のNULLは0または0Lなので