Какова цель использования NIL для представления нулевых узлов?


17

В моем курсе « Алгоритмы и структуры данных» профессора, слайды и книга ( Введение в алгоритмы, 3-е издание ) использовали слово NILдля обозначения, например, дочернего элемента узла (в дереве), который не существует.

Однажды, во время лекции, вместо того, чтобы сказать NIL, мой одноклассник сказал null, и профессор поправил его, и я не понимаю, почему профессора подчеркивают это слово.

Есть ли причина, по которой люди используют слово NILвместо null, или none, или любое другое слово? Имеет ли NILкакой-то конкретный смысл, которого нет у других? Есть ли какая-то историческая причина?

Обратите внимание, что я видел также несколько мест в Интернете, где, например, nullвместо этого использовалось слово NIL, но обычно используется последнее.

Ответы:


25

Насколько я обеспокоен, null, nil, noneи nothingявляются общими названиями для одной и той же концепции: значения , которое представляет «отсутствие значения», и который присутствует во многих различных типах (называемые обнуляемыми типов ). Это значение обычно используется, когда значение обычно присутствует, но может быть опущено, например, необязательный параметр. Разные языки программирования реализуют это по-разному, и некоторые языки могут не иметь такой концепции. В языках с указателями это нулевой указатель . Во многих объектно-ориентированных языках null не является объектом: вызов любого метода в нем является ошибкой. Чтобы привести несколько примеров:

  • В Лиспе nilобычно используется для обозначения отсутствия значения. В отличие от большинства других языков, nilимеет структуру - это символ по имени "NIL". Это также пустой список (потому что список должен быть cons-ячейкой, но иногда нет cons-ячейки, потому что список пуст). Реализовано ли это нулевым указателем под капотом или как символ, как любой другой, зависит от реализации.
  • В Паскале 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 похожая концепция использует имена Nothingи Just xдля значений, и Maybe aдля типа.

В представлениях алгоритма, какое имя используется, как правило, происходит от фона докладчика или языка, который используется в примерах кода.

В представлениях семантики разные имена могут использоваться для ссылки, например, на NULLидентификатор, который обозначает постоянную указателя в языке, и значение в семантике. Я не думаю, что есть какая-либо стандартная схема именования, и некоторые презентации оставляют это до различия шрифтов или вообще не переходят к конкретному синтаксису.NяL

Возможно, что ваш лектор хочет использовать слово nullдля константы нулевого указателя в языке программирования, используемом в курсе (Java или C #?), И NILдля обозначения отсутствия узла в некоторых структурах данных, которые могут быть или не быть реализованы как константа нулевого указателя (например, как показано выше, в Лиспе, NILчасто не реализуется как нулевой указатель). Это различие будет актуально при обсуждении методов реализации структур данных. При обсуждении самих структур данных концепция «нулевой указатель-константа» не имеет значения, имеет значение только концепция «не равно какому-либо другому значению».

Стандартной схемы именования не существует. Другой лектор или учебник могут использовать разные имена.


Еще два примера. Цель C имеет как NULL(для совместимости C), так и nil; Вызов методов на nilэто не работает. JavaScript имеет оба null(значение, не представляющее ничего) и undefined(значение даже не установлено).
200_успех

1
«В объектно-ориентированных языках null не является объектом: вызов любого метода для него является ошибкой». - Это относится не ко всем языкам, включая некоторые из перечисленных вами языков. В Ruby и Smalltalk nilэто объект, как и любой другой, он является экземпляром NilClass, другого понятия «нуль-ноль» нет, и, в частности, нет нулевого указателя. В Scala, Nilочень сильно отличается от null, nullявляется своего рода сортировкой, похожей на нулевой указатель, однако, он на самом деле имеет тип ( Null), Nilявляется обычным старым объектом, экземпляром синглтона EmptyListкласса, если хотите, и есть также…
Йорг Миттаг

1
NothingКоторый является нижним типом и не имеет экземпляра, и Unitкоторый является типом подпрограмм, которые не возвращают значение и имеют экземпляр singleton (). nullкаким-то образом несет в себе понятие «нулевой указатель» или «нулевая ссылка», не потому, что это как-то присуще термину, а просто из-за повсеместного распространения таких языков, как C, C ++, D, Java, C #, которые используют его в этом манера. NILне несет такой коннотации, хотя на самом деле используется таким образом, например, в Паскале, Модуле-2 и Обероне. В Ruby nilесть много полезных методов: nil.to_i # => 0, nil.to_s # => '', ...
Йорг W Mittag

1
... nil.to_a # => [], nil.to_h # => {}, nil.to_f # => 0.0, nil.inspect # => 'nil', и так далее. Вы можете увидеть полный список здесь .
Йорг Миттаг

3

Я полагаю, что причина использования как nil, так и null состоит в том, что первое - это, прежде всего, существительное, а второе - прилагательное (я проверил в Интернете и в своем бумажном словаре: American Heritage 1992).

Что касается значения и истории, NIL - это сокращение от латинского «nihil», что означает «ничто».

Насколько мне известно, использование имени nilдля обозначения нулевого указателя было введено с языком программирования Lisp (1958).

Указатель нуля является значением указателя , который должен указывать ничего, и поэтому их не следует разыменовывается. В большинстве случаев указатели являются просто адресами памяти. Любая переменная (т. Е. Любое местоположение), которая должна содержать такой указатель, всегда будет содержать некоторую конфигурацию битов, и любая такая конфигурация может быть прочитана как адрес памяти. Следовательно, часто случается, что значение nilбудет адресом области памяти, которая запрещена программе, таким образом вызывая некоторую форму сбоя (возможно прерывание), если программа пытается разыменовать nil, что может быть только ошибкой.

Наличие уникального предопределенного стандартного значения для выполнения этой роли является существенным в языках, использующих указатели в явном виде, поскольку важно иметь возможность проверить, действительно ли указатель указывает на какую-то область памяти или нет. Как правило, в Лиспе список создавался как последовательность пар «против», содержащих указатель «car» на элемент списка и указатель «cdr» на следующую пару. В последней паре списка второй указатель был nil.

Это соответствует рекурсивному определению списка как пустого списка или элемента списка, объединенного со списком. Следовательно, список без элемента был представлен как nil. Этот пустой список является идентификатором моноида списка.

Поскольку списки могут использоваться для представления наборов, пустой набор в этом случае также может быть представлен как nil.

Таким образом, nilисторически это было специальное значение указателя, но стало пониматься как специальное значение идентификатора для других более абстрактных областей, таких как списки или наборы.

Указатель, равный ему, nilбыл нулевым указателем, при этом нулевым является прилагательное, а не материальное (т. Е. Существительное).

Скоординированное использование как слова, как прилагательного, так и существительного вполне согласуется с другой практикой. Квалификатор null часто используется для нуля алгебраической структуры, такой как тождество моноида: нулевой элемент . Списки образуют моноид , где значение nil - это тождество. То же самое верно для множеств (хотя они образуют алгебру со многими другими свойствами). Аналогичным образом говорят, что целое число равно нулю, когда оно равно нулю.

Существует много вариаций использования этих слов и других, например ни одного, в зависимости от авторов и особенностей языков программирования.

Две основные коннотации , как объяснено выше

  • как стандартное «неопределенное значение», фактически представляющее отсутствие какого-либо полезного значения.

  • в качестве значения идентичности некоторого домена

Это показывает, что не совсем точно утверждать, что NIL - это « значение, которое представляет собой« отсутствие значения », как это сделал Жиль в принятом ответе . Это зависит от языка и его использования. Язык программирования LISP, вероятно, ввел NIL в терминологию программирования 55 лет назад. В LISP NILэто пустой список, и его можно эквивалентно отметить, ()что является естественным представлением пустого списка.Это не означает отсутствие значения. Иногда он используется в качестве заполнителя для пропущенных значений, хотя этого часто следует избегать именно потому, что пустой список является значением. Что означает отсутствующее значение в структуре в любом произвольном объекте, выбранном программистом, который нельзя спутать с приемлемыми значениями.

Эти два понятия довольно различны, хотя мы показали выше, что они могут быть связаны. Может быть интересно иметь детализированную таксономию режима использования терминологии, перечисленной Gilles'answer, чтобы увидеть, ориентировано ли использование каждого из этих слов в большей степени на одно значение или другое.

Имена не более чем то, что им назначено для обозначения в данном контексте, кем бы они ни определяли дискурс. Некоторые виды использования более распространены, более естественны или более последовательны, но всегда следует проверять определения и проверять, какое значение имело место в каждом контексте. И не всегда следует ожидать, что терминология будет выбрана со вкусом или последовательностью.


0

NIL - это объект со значением, которое сообщает программисту, что объект недопустим. Это особенно полезно в C ++, где NULL определяется как 0. Если вы отменяете ссылку на NULL в C ++, вы получаете неопределенное поведение. Если вы отмените ссылку на NIL (указатель на пустой объект, который вы определили), вы получите объект, который, как вы можете сказать, находится за пределами вашей структуры данных. Он отлично подходит для предотвращения катастрофических сбоев программ и выявления ошибок.

Вы можете использовать NIL в таких случаях, как списки с двойными связями, имея начало и конец списка для отслеживания как головы, так и хвоста, и следя за тем, чтобы указатели -> next и -> prev никогда не отменяли ссылку на NULL.


Насколько я вижу, это просто неправильно. В C ++ нет "NIL" .
Дэвид Ричерби

1
Я думаю, что вы неверно истолковали мой ответ. Ссылка, которую вы указали, никак не связана с моим ответом. Я предположил, что nil - это определенный пользователем объект, определенный для каждого класса, чтобы указать на пустой (но действительный) объект этого класса.
смещение

То, как вы пишете «NIL - это объект» (мой акцент), а не, скажем, «NIL может быть определен как объект», создает впечатление, что вы описываете функцию языка, а не стиль программирования. Однако, если ваш ответ связан исключительно со стилем программирования, то здесь речь идет не о теме.
Дэвид Ричерби
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.