Яка мета використання NIL для представлення нульових вузлів?


17

У моєму курсі " Алгоритми та структури даних" професори, слайди та книга ( Вступ до алгоритмів, 3-е видання ) використовували слово NILдля позначення, наприклад, дочірнього вузла (на дереві), якого не існує.

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

Чи є причина, чому люди використовують слово NILзамість null, або none, або будь-яке інше слово? Чи NILмає якийсь особливий сенс, якого інші не мають? Чи є якась історична причина?

Зауважте, що я бачив також декілька місць в Інтернеті, де, наприклад, слово nullвикористовувалось замість NIL, але зазвичай використовується це останнє.

Відповіді:


25

Наскільки я стурбований, null, nil, noneі nothingє загальними назвами для однієї і тієї ж концепції: значення , яке представляє «відсутність значення», і який присутній у багатьох різних типах (звані обнуляє типів ). Це значення зазвичай використовується там, де значення зазвичай є, але може бути опущено, наприклад, необов'язковий параметр. Різні мови програмування реалізують це по-різному, і деякі мови можуть не мати такої концепції. У мовах з покажчиками це нульовий покажчик . У багатьох об'єктно-орієнтованих мовах 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 подібне поняття використовує назви Nothingі Just xдля значень, і Maybe aдля типу.

В алгоритмі презентацій, яке ім'я використовується, як правило, походить від фону презентатора або мови, що використовується в прикладах коду.

У презентаціях семантики різні імена можуть використовуватися для позначення, наприклад, NULLідентифікатора, який позначає константу вказівника в мові, і значення у семантиці. Я не думаю, що існує якась стандартна схема іменування, і деякі презентації залишають це різницею шрифту або взагалі не переходять у конкретний синтаксис.нiл

Можливо, що ваш викладач хоче використовувати слово nullдля константи нульового покажчика в мові програмування, що використовується в курсі (Java або C #?), І NILпозначити відсутність вузла в деяких структурах даних, які можуть бути, а можуть і не бути реалізовані. як константа нульового покажчика (наприклад, як видно вище, в Lisp, NILчасто не реалізується як нульовий покажчик). Ця відмінність буде доречною при обговоренні методів реалізації структур даних. Під час обговорення самих структур даних концепція константа нуля-вказівника не має значення, має значення лише концепція, що не відповідає рівним значенням.

Не існує стандартної схеми іменування. Інший викладач чи підручник міг використовувати різні назви.


Ще два приклади. Ціль C має як NULL(для сумісності з C), так і nil; виклик методів nil- це не-оп. У JavaScript є як null(значення нічого не представляє), так і undefined(значення навіть не встановлено).
200_успіх

1
"У об'єктно-орієнтованих мовах null не є об'єктом: виклик будь-якого методу на ньому - це помилка." - Це не стосується всіх мов, включаючи деякі з перелічених вами мов. У Ruby and Smalltalk nilце об'єкт, як і будь-який інший, це екземпляр NilClass, немає іншого поняття "null-ness", і, зокрема, немає null-pointer. У Scala Nilдуже відрізняється від того null, nullє свого роду сортом, як нульовий вказівник, однак, він насправді має тип ( Null), Nilзвичайний старий об'єкт, одиночний екземпляр EmptyListкласу, якщо ви хочете, а також є…
Jörg W Mittag

1
NothingЯкий є найнижчим типом і не має примірника, і Unitякий є типом підпрограми, яка не повертає значення і має одиночний екземпляр() . nullякимось чином несе в собі поняття "нульовий покажчик" або "нульова посилання", не тому, що якимось чином притаманне терміну, а просто через всюдисутність мов, таких як C, C ++, D, Java, C #, які використовують його в цьому манера. NILне містить цієї конотації, хоча вона фактично використовується таким чином, наприклад, у Pascal, Modula-2 та Oberon. В 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', і так далі. Повний список можна переглянути тут .
Йорг W Міттаг

3

Я вважаю, що причина вживання як нуля, так і нуля полягає в тому, що перше - це насамперед іменник, а останнє - насамперед прикметник (я перевірив в Інтернеті та в своїй статті «Американська спадщина 1992»).

Щодо значення та історії, NIL - це скорочення від латинського "nihil", що означає "нічого".

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

Покажчик нуля є значенням покажчика , який повинен вказувати нічого, і тому їх не слід разименовивается. У більшості випадків покажчики - це просто адреси пам'яті. Будь-яка змінна (тобто будь-яке розташування), яка призначена для утримання такого вказівника, завжди буде містити певну конфігурацію бітів, і будь-яка така конфігурація може читатися як адреса пам'яті. Тому часто трапляється так, що значенням nilбуде адреса області пам’яті, забороненої програмі, тим самим спричиняючи певну форму відмови (можливо, переривання), якщо програма намагається скинути nil, що може бути лише помилкою.

Наявність унікального заздалегідь визначеного стандартного значення для відігравання цієї ролі є важливим для мов, які чітко використовують покажчики, оскільки важливо мати можливість перевірити, чи покажчик вказує на місце розташування пам'яті чи ні. Як правило, в Ліспі список був побудований як послідовність пар "проти", що містять вказівник "автомобіль" на елемент списку та вказівник "cdr" на наступну пару. В останній парі списку був другий покажчик nil.

Це відповідає рекурсивному визначенню списку як порожнього списку, або елементу списку, об'єднаного у список. Отже, список без елемента був представлений nil. Цей порожній список, як відомо, є особою моноїду списку.

Оскільки списки можна використовувати для представлення наборів, порожній набір у цьому випадку також може бути представлений символом nil.

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

Вказівник, що дорівнює, nilбув нульовим вказівником, нуль - це прикметник, а не предметний (тобто іменник).

Узгоджене використання обох слів, як прикметника, так і іменника цілком відповідає іншій практиці. Класифікатор null часто використовується для нуля алгебраїчної структури, наприклад ідентичності моноїда: елемент null . Списки утворюють моноїд , де значенням нуль є тотожність. Те саме стосується множин (хоча вони утворюють алгебру з набагато більшими властивостями). Можна сказати аналогічно, що ціле число є нульовим, коли воно дорівнює нулю.

Існує безліч варіацій використання цих слів інших, таких як жоден, залежно від авторів та ідіосинкразії мов програмування.

Дві основні конотації є пояснено вище,

  • як стандартне "невизначене значення", що фактично представляє відсутність будь-якої корисної вартості.

  • як значення ідентичності деякого домену

Це показує, що не зовсім точно стверджувати, що NIL - це " величина, яка представляє" відсутність значення ", як це робив Гілз у прийнятій відповіді . Це залежить від мови та її використання. Мова програмування LISP ймовірно, запровадила NIL в термінології програмування 55 років тому. У LISP NIL- це порожній список, і можна рівнозначно зазначити, ()яке є природним поданням порожнього списку.Це не означає відсутність значення. Іноді він використовується як тримач місць для відсутніх значень, хоча цього часто уникати саме тому, що порожній список є значенням. Що означає відсутність значення в структурі в будь-якому довільному об'єкті, обраному програмістом, яке не можна переплутати з прийнятними значеннями.

Дві концепції досить різні, хоча ми вже показали, що вони можуть бути пов'язані. Можливо, буде цікавим детальний таксономічний прийом використання термінології, перерахованої Гіллесансвером, щоб побачити, чи вживання кожного з цих слів орієнтоване більше на одну конотацію чи іншу.

Імена - це не більше ніж те, що їм призначено означати в даному контексті тим, хто визначає дискурс. Деякі способи використання є більш поширеними, більш природними або більш послідовними, але завжди слід перевіряти визначення та переконатися, яке значення передбачалося у кожному контексті. І не завжди слід очікувати, що термінологія була обрана зі смаком чи послідовністю.


0

NIL - об'єкт зі значенням, який повідомляє програмісту, що об'єкт недійсний. Це особливо корисно для C ++, де NULL визначається як 0. Якщо ви скасуєте NULL у C ++, ви отримаєте невизначене поведінку. Якщо ви скасуєте NIL (вказівник на порожній об'єкт, який ви визначили), ви отримаєте об'єкт, про який можна сказати, поза межами вашої структури даних. Це чудово для запобігання катастрофічних збоїв програми та виявлення помилок.

Ви можете використовувати NIL у таких випадках, як подвійно пов'язані списки, якщо це буде початок і кінець списку, щоб відслідковувати як голову, так і хвіст, і переконайтесь, що -> наступний і -> попередні покажчики ніколи не знімають посилання на NULL.


Наскільки я бачу, це просто неправильно. У C ++ немає "NIL" .
Девід Річербі

1
Я думаю, ви неправильно трактували мою відповідь. Надане вами посилання не відповідає моїй відповіді. Я запропонував, що nil - це визначений користувачем об'єкт, визначений на основі класу, щоб вказати на порожній (але дійсний) об'єкт цього класу.
абаст

Те, як ви пишете "NIL - це об'єкт" (мій акцент), а не, скажімо, "NIL можна визначити як об'єкт", робить його схожим на те, що ви описуєте мовну особливість, а не стиль програмування. Однак, якщо ваша відповідь суто стосується стилю програмування, тут це не зовсім тематично.
Девід Річербі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.