Null(ヌル、ナル)は、何もない、という意味で、プログラミング言語などコンピュータ関係では、「何も示さないもの」を表すのに使われる。同様のものとして、PascalにおけるNil(ニル)、PythonにおけるNone(ナン)、VB.NETにおけるNothing(ナッシング)のように、他のキーワード(予約語)や識別子が使われることもある。
ドイツ語において Null は数値の0(ゼロ)を意味し、発音は /nʊl/ である。一方、英語において null は /nʌl/ と発音される。ドイツ語においても、数値の0と区別するために、本記事の意味の Null は英語風に /nʌl/ と発音される場合がある。
日本においては「ヌル」という発音が定着しているが、英語読みに近い「ナル」という発音で呼ばれる場合もある。例えば、JISのJIS X 3005-1:2014「データベース言語SQL 第1部:枠組(SQL/Framework)」(日本産業標準調査会、経済産業省)のP4には「ナル値 (Null Value)」、JIS X 3010:2003「プログラム言語C」(日本産業標準調査会、経済産業省)のP4には「ナル文字 (Null Character)」という記述がある。この他にも専門書や国家試験でも見られる。
プログラミング言語などにおいて、nullやnilといったキーワード(予約語)あるいは識別子(定数名)などの意味がどういったものかは言語による。場合によっては同じ言語であっても処理系の実装や言語バージョンごとに違うことさえある。ポインタや参照のある言語では、ヌルポインタまたはヌル参照などと呼ばれる何も指さない特別なポインタや参照であることもあるし、Pythonのようにオブジェクトのひとつであることもある。古典的なLISPのように真理値の偽(の代表)や空リスト「()」を兼ねたもの(それらと同じもの)だったりすることもある。
語源
ラテン語で「無」を意味する nullusに由来する。nil もラテン語の nihil の短縮形に由来する。
英語では null はコンピュータに限らず使われ、しばしば zero または empty と交換可能である。例えば、null matrix は zero matrix(零行列)、null set は empty set(空集合)と同義である。ただし、empty matrix すなわち空行列は行数または列数の少なくとも一方が0であるような行列を指し、零行列とは別の概念である。また、null string は empty string(空文字列)と同一視されることもあれば、ヌル参照を意味することもある。一般的なプログラミング言語において、ポインタ変数や参照変数が無効値nullを指している状態と、長さ0の有効な空文字列や空リストなどを指している状態は明確に区別される。
ヌルポインタ
ポインタの値が無効であることを示す。C言語では無効ポインタを表現するための特別な定数値(ヌルポインタ定数)として、実装定義(処理系定義)のNULLマクロが用意されている。Cの規格ではNULLポインタの内部数値は0とは規定されていないが、0をポインタ型にキャストするとヌルポインタになることは規定されているので、(C17規格までの)代表的な実装では以下のようになっている。
またC言語から派生したC では、C言語から引き継いだNULLマクロが標準化されており、こちらも実装定義となっている。ただし、Cとは違って汎用ポインタ型void*から他の型へのポインタに暗黙変換することを禁止したため、C 03規格までは以下のように整定数0に展開される実装が一般的であった。
しかし、これは基本整数型intの0と型システムの上では同じになるため、しばしばオーバーロードの呼び間違いが生じることとなった。これを解消するためC 11規格では専用のstd::nullptr_t型を持つリテラルを表すnullptrキーワードが導入された。C 11以降は、NULLマクロはnullptrに展開される実装もありえる。のちにCにおいても、C23規格にて同様のnullptrが導入された。
なお、JIS X 3010:2003やJIS X 3014:2003の文面では、翻訳元であるISO/IEC 9899:1999やISO/IEC 14882:2003の文面で使われているnull pointerの対訳として「空ポインタ」と表記されているが、一般的にはヌルポインタと呼ばれることのほうが多い。
ヌル参照
JavaやC#に代表されるように、C よりも後発の言語ではnullを最初から専用構文として導入した事例が多い。
Javaには構文上ポインタは存在せず、代わりにガベージコレクションによる自動メモリ管理の対象となる「参照型」のインスタンスを指すための「参照」が用いられる。無効な参照を表す定数にはnullキーワードが使用される。
C#では、ガベージコレクションによる管理対象となる参照型、ポインタ、および値型をラップするジェネリック型として定義されているNullable型(System.Nullable構造体)の無効値を表す定数として、一律nullキーワードが使用される。
その他のヌル
PythonではNoneという名前で、その値は組み込みオブジェクトである。バージョン2.4からNoneには代入できなくなった。
Rubyではnilという予約語で、意味は組み込みオブジェクト(NilClassの唯一のインスタンス)である。
VB.NETではNothingというキーワードで、任意のデータ型の既定値を表す。
LISPではNILで、どれでも同じようなものだが実体の詳細は様々で、carやcdrをとるとそれぞれでまたnilが返ってくる実装もあればエラーになる実装もある(普通はnilかどうかをまずテストして、carやcdrしないようにする)。
Windows APIのGraphics Device Interface (GDI) では、何も描画しない空のペンやブラシとして、予約済みのオブジェクトを取得するための定数値NULL_PENおよびNULL_BRUSHが用意されている。これらを指定したときにGetStockObject()関数から返却される値はHGDIOBJ型の有効なオブジェクトハンドルであり、ヌルポインタとは異なる。
null型
構文上、nullは多くの言語で特別なnullリテラルという扱いだが、リテラルのための型「null型」(またはNull型、NULL型とも)が規定される言語が存在する。null型の値はnullのみが許される。
プログラミング言語の文法上null型が存在するケースでは、一般的な型同様にnull型を用いることが出来るが、null型を扱えない言語も存在する。
例えばJavaでは「null型」はあるが、ユーザーコードで利用することはできない。言語仕様では、nullリテラルはnull型であり、null型には名前がなく、null型の変数宣言やnull型へのキャストをすることは不可能である、という扱いとなっている。以上より、null型は内部的に存在するが、構文などの上でそれを扱うことができず、その値を表すリテラルのみが存在する。
ヌル文字
ヌル文字列
nullデバイス
nullデバイスは、存在しない架空のデバイスを表す。nullデバイスに出力すると、実際はどこにも出力されず廃棄される。
UNIXやLinuxでは/dev/null、MS-DOSやMS WindowsではNULで表される。
データベースのNULL
データベースのNULLは、欄が空欄であることを示す。これは人が読む用の表(ひょう)のNAにあたり、C言語のNULLよりは浮動小数点演算のNaN(非数)に近い。
具体的にはNULLには、未知・不明 (Unknown) の場合と適用不能・非存在 (Not Applicable, Inapplicable) の場合がある。例えば、名前がNULLの場合、未知のNULLは「名前はあるが分からない」ということを、適用不能のNULLは「名前が存在しない」(例えば、独身者の配偶者の名前)ことを示す。これはエドガー・F・コッドによる分類だが、彼はさらに詳細な分類をしている。
なおそれらに対し、名前欄が空文字列の場合は、(事前の取り決めがなければ)名前はあり、知っていて、欄に書かれている通り「」であることを示す。未知や適用不能のために、空文字列、文字列 'UNKNOWN'、0、-1、9999年12月31日、未使用のコードなど特定のありえない値を例外値として使うことがしばしばあるが、それらは実際の値であるとして処理されてしまう危険がある。
NULLはNULL値(あるいは空値)と呼ばれることもあるが、コッドによると値ではない(特殊な値や例外的な値ではない)。値ではないので型もない。整数型の列にあるNULLも文字列型の列にあるNULLも同じNULLであり、NULL整数・NULL文字列などの区別はない。内部的にはNULLは、(NaNやヌルポインタのような)特定のビット列ではなく、値とは別個の「NULLかどうか」を表すメモリ領域で管理されていることが多い。
SQLのNULL
NULL を含む演算の結果
NULLを含む演算の多くは結果がNULLとなる。例えば
はいずれもNULLである(0で割っても0除算は発生しない)。これは浮動小数点演算でNaNを含む式の結果がNaNになるのと似た規定である。この規定によりNULLを許容する演算は煩雑になりやすくなることから、データーベース・ベンダーによる拡張が行われている場合がある。この問題は、WHERE句でNULLでありうる列を診断しようとしたとき、特にDELETEやUPDATEで悲惨な結果を呼ぶことがある。回避方法は、NULLが混入する可能性を充分に検討し、IS NULL 演算子を駆使して式を慎重に組み立てる以外にない。
ただし少なからず場合に、NULLを含む演算で結果がNULL以外になる。このためNULLは無制限には伝播しない。ただししばしば、NULLの絡んだ演算の実装は不完全で、処理系依存が多い。
比較・IN述語など論理値を返すべき場面では、NULLを含む結果は UNKNOWN となる。UNKNOWN は、値ではないNULL(あるいは「不明 Unknown のNULL」)とは異なり TRUE(真)・FALSE(偽)に並ぶ第3の論理値である。例えば
などはいずれもUNKNOWNになる。ただし、UNKNOWNの扱いにもNULLに似た難しさがある。
論理式でNULLとならない場合がある。
はそれぞれFALSE、TRUEである(NULL AND TRUE、NULL OR FALSE がNULLになるのとの違いに注意)。
Oracleは空文字列とNULLを区別しないため、NULL あるいは空文字列を含む演算で非標準な結果となることがある。例えば、文字列と NULL を連結すると本来は NULL になるが、Oracleでは文字列の値を変えない(ただし NULL 同士の連結は NULL になる)。
NULLを扱うための工夫
テーブルの各列には、NULLを保持できないと指定することができる。例えば、全ての行で必ず異なる値が含まれなければならないと指定されている列であっても、複数の行がNULLを保持できてしまう。そこで、この列にNULLを保持できないと指定すればこの問題が回避できる。
ソートでは、NULLはいかなる値よりも小さいとして扱われる(ただしOracleは逆にいかなる値よりも大きいとして扱われるが、オプションで変更できる)。しかし論理値でのソートが実装されていれば、以下のように IS (NOT) NULL を第1のソートキーに使ってNULLを先または後に変更できる。
また、CASE式やCOALESCE関数(あるいはOracleならNVL関数も可)を使って、NULLに任意の値を割り当ててソートすることができる。以下の句はいずれも、colがNULLならば0を割り当ててソートする。
脚注
注釈
出典
関連項目
- ヌルポインタ
- Nullable型


:max_bytes(150000):strip_icc()/null_hypothesis-ADD-SOURCE-795b6f885fe04e8795d30a253a2f46ba.jpg)

