nullノードを表すためにNILを使用する目的は何ですか?


17

私のAlgorithms and Data Structuresコースでは、教授、スライド、および本(Introduction to Algorithms、第3版NILは、たとえば存在しないノード(ツリー内)の子を示すためにこの単語を使用しています。

かつて、講義中NILに、クラスメートが言ったのではなく、と言ったのですが、null教授は彼を修正しましたが、教授がこの言葉を強調する理由がわかりません。

人々NILnull、またはnone、または他の単語の代わりに単語を使用する理由はありますか?ないNIL他の人が持っていないことをいくつかの特定の意味がありますか?歴史的な理由はありますか?

また、ウェブのいくつかの場所で、たとえばのnull代わりに単語が使用されているのを見たことがあることに注意してくださいNIL。通常、この最後の単語が使用されます。

回答:


25

これまで私は心配のように、nullnilnonenothing同じコンセプトのための共通の名前である「価値の不在」を表す値、および多くの異なる種類(と呼ばれる中に存在するNULL可能なタイプを)。この値は通常、値が通常存在する場合に使用されますが、オプションのパラメーターなど、省略される場合があります。異なるプログラミング言語はこれを異なる方法で実装し、一部の言語はそのような概念を持たない場合があります。ポインターのある言語では、nullポインターです。多くのオブジェクト指向言語では、nullはオブジェクトではありません。nullでメソッドを呼び出すとエラーになります。いくつかの例を挙げます:

  • Lispでは、nil一般に値の欠如を表すために使用されます。他のほとんどの言語とは異なり、nil構造を持っています—それは名前がのシンボルです"NIL"。空のリストでもあります(リストはコンスセルである必要がありますが、リストが空のためコンスセルがない場合もあります)。ボンネットの下のヌルポインターによって実装されるか、他のシンボルとして実装されるかは、実装に依存します。
  • Pascalでは、nil逆参照されない可能性のあるポインター値(任意のポインタータイプで有効)です。
  • CおよびC ++では、すべてのポインタータイプにはNULL、有効なオブジェクトへのポインターとは異なる値が含まれます。
  • Smalltalkでは、nilメソッドが定義されていないオブジェクトです。
  • JavaおよびC#ではnull、任意のオブジェクトタイプの値です。フィールドまたはメソッドにアクセスしようとnullすると、例外がトリガーされます。
  • Perlでは、undef他のスカラー値とは異なり、「実際の」値がないことを示すために言語およびライブラリ全体で使用されます。
  • Pythonでは、Noneは他の値とは異なり、言語およびライブラリ全体で使用され、「実際の」値がないことを示します。
  • ML(SML、OCamlの)において、None型スキームにおける任意の型の値で'a option含まれ、NoneそしてSome x任意用x'a
  • Haskellでは、同様のコンセプトで名前NothingJust xMaybe a、型を使用しています。

アルゴリズムのプレゼンテーションでは、どの名前が使用されるかは、プレゼンターの背景やコード例で使用される言語に由来する傾向があります。

セマンティクス表示では、異なる名前を使用して、たとえばNULL言語のポインター定数を示す識別子や、セマンティクスの値を参照できます。標準的な命名体系はないと思います。また、プレゼンテーションによってはフォントの違いに任せられたり、具体的な構文にならないことがあります。nil

講師がnull、コースで使用されるプログラミング言語(JavaまたはC#?)のヌルポインター定数の単語を使用したり、NIL実装されている場合とされていない場合があるデータ構造にノードがないことを示したりする可能性がありますnullポインター定数として(たとえば、上記のLispではNIL、nullポインターとして実装されていないことがよくあります)。この区別は、データ構造の実装手法を議論するときに関連します。データ構造自体を議論するとき、null-pointer-constantの概念は無関係であり、等しくないものと他の値の概念だけが重要です。

標準の命名スキームはありません。別の講師または教科書では、異なる名前を使用できます。


さらに2つの例。Objective CにNULL(Cとの互換性のため)とnil;の両方があります。メソッドの呼び出しnilは何もしません。JavaScriptにnull(何も表さない値)とundefined(値が設定されていません)の両方があります。
200_success

1
「オブジェクト指向言語では、nullはオブジェクトではありません。nullでメソッドを呼び出すとエラーになります。」–これは、リストした言語の一部を含むすべての言語に当てはまるわけではありません。RubyおよびSmalltalkでは、nil他のオブジェクトと同様のオブジェクトNilClassであり、のインスタンスです。他の「ヌルネス」の概念はなく、特にヌルポインターはありません。スカラ座では、Nil非常に異なるからであるnullnull(但し、それは実際に型を持つ、ヌル・ポインタのようなちょっと-みかんでNull、)Nil定期的に古いオブジェクトのシングルトンインスタンスですEmptyList、ともありますがする場合、クラスは...
ヨルグWミットタグ

1
Nothingこれは一番下の型であり、インスタンスはありません。また、Unitこれは値を返さず、シングルトンインスタンスを持つサブルーチンの型です()null「nullポインタ」または「null参照」の概念を何らかの形で持っています。これは、用語に何らかの形で固有のものではなく、これで使用するC、C ++、D、Java、C#などの言語の遍在のためですマナー。NILPascal、Modula-2、Oberonなどで実際に使用されている場合でも、この意味合いは含まれません。Rubyでは、nil多くの有用なメソッドがありますnil.to_i # => 0nil.to_s # => ''...
イェルクWミッターク

1
... nil.to_a # => []nil.to_h # => {}nil.to_f # => 0.0nil.inspect # => 'nil'、など。完全なリストはこちらでご覧いただけます
ヨルグWミットタグ

3

nilnullの両方を使用する理由は、前者は主に名詞であり、後者は主に形容詞であるためだと思います(Webおよび私の論文辞書:American Heritage 1992で確認しました)。

意味と歴史に関して、NILはラテン語「nihil」からの縮約であり、「無」を意味します。

私の知る限り、ヌルポインターnilを示す名前の使用は、プログラミング言語Lisp(1958)で導入されました。

NULLポインタが何を指すようになっているポインタ値であるため、間接参照すべきではありません。ほとんどの場合、ポインタは単なるメモリアドレスです。そのようなポインターを含むことを目的とする変数(つまり、任意の場所)には常にビットの構成が含まれ、そのような構成はメモリアドレスとして読み取ることができます。したがって、多くの場合、値nilはプログラムで禁止されているメモリ領域のアドレスであるため、プログラムが逆参照しようとするとエラー(何らかのエラー)が発生し、何らかの形式の障害(割り込みの可能性)nilが発生します。

ポインタが明示的にメモリ位置を指しているかどうかをテストできることが重要であるため、ポインタを明示的に使用する言語では、この役割を果たすための一意の定義済み標準値が不可欠です。通常、Lispでは、リストはリスト要素への「car」ポインタと次のペアへの「cdr」ポインタを含む「cons」ペアの連続として構築されました。リストの最後のペアでは、2番目のポインターはでしたnil

これは、空のリスト、またはリストに連結されたリスト要素としてのリストの再帰的な定義に対応します。したがって、要素のないリストはで表されましたnil。この空のリストは、たまたまリストモノイドのIDです。

リストはセットを表すために使用できるため、その場合は空のセットもで表すことができnilます。

したがって、nil歴史的には特別なポインタ値でしたが、リストやセットなどの他のより抽象的なドメインの特別なアイデンティティ値として理解されるようになりました。

等しいポインターnilはNULLポインターであり、NULLは実体(つまり名詞)ではなく形容詞です。

形容詞と名詞としての両方の単語の調整された使用は、他の慣行と非常に一貫しています。修飾子nullは、モノイドのIDなどの代数構造のゼロによく使用されますnull element。リストはモノイドを形成します。値nilはIDです。同じことがセットにも当てはまります(ただし、より多くのプロパティを持つ代数を形成します)。同様に、整数がゼロの場合は整数であると言います。

著者やプログラミング言語の特異性に応じて、これらの単語の使用には他にも多くのバリエーションがあります(noneなど)。

二つの主要な意味合いがある上述したように、

  • 実際に使用可能な値がないことを表す、標準の「未定義の値」として。

  • あるドメインのアイデンティティ値として

これは、受け入れられた回答で Gillesによって行われたように、NILが「値の欠如」を表す値であると断言することはまったく正確ではないことを示しています。言語とその用途に依存します。プログラミング言語LISPは、おそらく55年前にプログラミング用語ではNILを導入しました。LISPでは、NILは空のリストであり、空のリスト()の自然な表現であることに注意してください。値がないことを表すものではありません。空のリストは値であるため、これはしばしば正確に回避する必要がありますが、欠損値のプレースホルダーとして使用されることがあります。プログラマが選択した、許容可能な値と混同できない任意のオブジェクトの構造の欠損値を意味するもの。

上記で示したように、2つの概念は関連していることがありますが、2つの概念はかなり異なります。Gillesの回答で列挙されている用語の使用に関する詳細な分類法を用意して、これらの各単語の使用がどちらかの意味を重視しているかどうかを確認することは興味深いかもしれません。

名前は、談話を定義している人によって、与えられたコンテキストで意味するために割り当てられたものにすぎません。一部の使用法はより一般的、より自然、またはより一貫していますが、常に定義を確認し、各コンテキストで意図されている意味を確認する必要があります。また、味や一貫性のある用語が選択されていることを常に期待するべきではありません。


0

NILは、オブジェクトが無効であることをプログラマに伝える値を持つオブジェクトです。NULLが0として定義されているC ++で特に役立ちます。C++でNULLを逆参照すると、未定義の動作が発生します。NIL(定義した空のオブジェクトへのポインター)を逆参照すると、データ構造の終わりを超えていることがわかるオブジェクトを取得します。壊滅的なプログラムの失敗を防ぎ、エラーを検出するのに最適です。

二重リンクリストのような場合にNILを使用して、先頭と末尾の両方を追跡するリストの先頭と末尾にし、-> nextおよび-> prevポインターがNULLを間接参照しないようにします。


私が見る限り、これは単に間違っています。C ++には「NIL」はありません
デビッドリチャービー

1
あなたは私の答えを誤解したと思います。あなたが提供したリンクは私の答えとは関係ありません。nilは、クラスごとに定義され、そのクラスの空の(ただし有効な)オブジェクトを指すユーザー定義オブジェクトであることを提案しました。
中絶

「NIL オブジェクトとして定義できる」というよりも「NIL オブジェクトです」(私の強調)と書くと、プログラミングのスタイルではなく、言語機能を記述しているように見えます。ただし、答えが純粋にプログラミングスタイルに関するものである場合は、ここではあまり話題になりません。
デビッドリチャービー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.