널 노드를 나타내는 데 NIL을 사용하는 목적은 무엇입니까?


17

알고리즘 및 데이터 구조 과정에서 교수, 슬라이드 및 책 ( Algorithms 소개, 3 판 )은 NIL예를 들어 존재하지 않는 노드 (트리의)의 자식을 나타내는 단어 를 사용하고 있습니다.

한 번 강의 중에라는 말 대신에 NIL내 반 친구가 말했다 null. 교수가 그를 교정했는데 교수가 왜이 단어를 강조하는지 이해할 수 없다.

사람들 NILnull, 또는 none, 또는 다른 단어 대신 단어 를 사용하는 이유가 있습니까? 않는 NIL다른 사람이하지 않는 어떤 특별한 의미가? 역사적인 이유가 있습니까?

예를 들어, null대신 단어 가 사용 NIL되었지만 웹 에서이 마지막 단어 가 사용되는 웹의 일부 위치도 보았습니다 .

답변:


25

마찬가지로 지금까지 내가 걱정으로, null, nil, nonenothing같은 개념에 대한 일반적인 이름입니다 : 다양한 종류에 존재하는 "값의 부재"를 나타내는 값, 그리고 (라고 nullable 형식을 ). 이 값은 일반적으로 값이 일반적으로 존재하는 경우에 사용되지만 선택적 매개 변수와 같이 생략 될 수 있습니다. 다른 프로그래밍 언어는이를 다르게 구현하며 일부 언어에는 그러한 개념이 없을 수 있습니다. 포인터가있는 언어에서는 널 포인터 입니다. 많은 객체 지향 언어에서 null은 객체가 아닙니다. 메소드를 호출하는 것은 오류입니다. 몇 가지 예를 들자면 :

  • Lisp에서는 nil일반적으로 값이 없음을 나타내는 데 사용됩니다. 대부분의 다른 언어와 달리 nil구조가 "NIL"있습니다. 이름은 입니다. 또한 목록이 빈 셀이기 때문에 빈 목록이기도합니다 (목록이 비어 있기 때문에 때때로 빈 셀이 없음). 후드 아래의 널 포인터로 구현되는지 또는 다른 기호로 구현되는지 여부는 구현에 따라 다릅니다.
  • Pascal에서 nil역 참조 할 수없는 포인터 값 (모든 포인터 유형에 유효)입니다.
  • C 및 C ++에서 모든 포인터 유형에는 NULL유효한 객체에 대한 포인터와 다른 값이 포함됩니다 .
  • Smalltalk에서 nil메서드가 정의되지 않은 개체입니다.
  • Java 및 C #에서 null모든 객체 유형의 값입니다. 필드 또는 메소드에 액세스하려고 null하면 예외가 발생합니다.
  • Perl에서는 undef다른 스칼라 값과 구별되며 언어 및 라이브러리 전체에서 "실제"값이 없음을 나타내는 데 사용됩니다.
  • 파이썬에서는 None다른 값과 구별되며 언어와 라이브러리 전체에서 "실제"값이 없음을 나타 내기 위해 사용됩니다.
  • ML (SML, OCaml의)에서, None유형 방식으로 임의의 타입의 값이 'a option포함 None하고 Some x있는 대 x'a.
  • Haskell에서 유사한 개념은 이름 NothingJust x값 및 Maybe a유형에 사용됩니다.

알고리즘 프레젠테이션에서 사용되는 이름은 발표자의 배경 또는 코드 예제에 사용 된 언어에서 유래하는 경향이 있습니다.

NULL나는

강사가 강의에서 사용 된 null프로그래밍 언어 (Java 또는 C #?)에서 널 포인터 상수에 해당 하는 단어를 사용하고 NIL일부 데이터 구조에 노드가 없음을 나타내거나 구현하지 않을 수 있습니다. 예를 들어 Lisp에서 위에서 볼 수 있듯이 널 포인터 상수로 NIL구현되지 않는 경우가 많습니다. 이 차이점은 데이터 구조에 대한 구현 기술을 논의 할 때 관련이 있습니다. 데이터 구조 자체를 논의 할 때 널 포인터 상수 개념은 관련이 없으며 다른 값과 같지 않은 개념 만 중요합니다.

표준 명명 체계가 없습니다. 다른 강사 또는 교과서는 다른 이름을 사용할 수 있습니다.


두 가지 예가 더 있습니다. 목표 CNULL(C 호환성을 위해) 및 nil; 호출 메소드 nil는 작동하지 않습니다. JavaScript 에는 null(아무것도 나타내는 값)과 undefined(값이 설정되어 있지 않음)이 있습니다.
200_success

1
"객체 지향 언어에서 null은 객체가 아닙니다. 메소드를 호출하는 것은 오류입니다." – 이것은 나열된 일부 언어를 포함하여 모든 언어에 해당되는 것은 아닙니다. 루비와 스몰 토크에서는 nil다른 객체와 같은 객체입니다 NilClass.이 인스턴스 는 "null-ness"라는 다른 개념이 없으며 특히 널 포인터가 없습니다. 스칼라에서 Nil매우 독특한으로부터 null, null(그러나 실제로 유형이, 널 포인터와 같은 좀-그렇다고이다 Null) Nil정기적 된 객체의 싱글 인스턴스이며 EmptyList, 또한 거기 당신이 경우 클래스는 ...
Jörg W Mittag

1
Nothing이것은 맨 아래 유형이며 인스턴스가 없으며, Unit값을 반환하지 않고 싱글 톤 인스턴스를 갖는 서브 루틴 유형입니다 (). null어쨌든 "널 포인터"또는 "널 참조"라는 개념을 가지고 있습니다. 이는 용어에 내재 된 것이 아니라 단순히 C, C ++, D, Java, C #와 같은 언어의 편재성 때문입니다. 방법. NILPascal, Modula-2 및 Oberon에서 실제로 사용되는 경우에도이 의미를 갖지 않습니다. 루비에서 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', 등. 여기 에서 전체 목록을 볼 수 있습니다 .
Jörg W Mittag

3

나는 nilnull 을 모두 사용하는 이유 는 전자가 주로 명사이고 후자가 주로 형용사 이기 때문이라고 생각합니다 ( 과 논문 사전에서 확인 했습니다 : American Heritage 1992).

의미와 역사와 관련하여 NIL 은 "아무것도"를 의미하는 라틴어 "nihil"의 축소입니다.

내가 nil알기로는 널 포인터 를 나타내는 이름 을 사용하는 것이 프로그래밍 언어 Lisp (1958) 와 함께 소개되었습니다 .

널 포인터는 아무것도 가리하도록되어 포인터 값, 따라서 역 참조 할 수 없습니다. 대부분의 경우 포인터는 단순히 메모리 주소입니다. 이러한 포인터를 포함하는 모든 변수 (즉, 모든 위치)에는 항상 비트의 일부 구성이 포함되며 이러한 구성은 메모리 주소로 읽을 수 있습니다. 따라서 값 nil이 프로그램에 금지 된 메모리 영역의 주소가 되는 경우가 종종 있으므로 프로그램이 역 참조를 시도 nil하면 오류가 발생할 수있는 일부 형태의 실패 (중단 가능) 가 발생합니다.

포인터가 명시 적으로 일부 메모리 위치를 가리키는 지 여부를 테스트 할 수 있어야하므로 포인터를 명시 적으로 사용하는 언어에서는이 역할을 수행하기 위해 고유 한 사전 정의 된 표준 값을 갖는 것이 필수적입니다. 일반적으로 Lisp에서 목록은 목록 요소에 대한 "car"포인터와 다음 쌍에 대한 "cdr"포인터를 포함하는 "cons"쌍의 연속으로 작성되었습니다. 목록의 마지막 쌍에서 두 번째 포인터는 nil입니다.

이것은 빈 목록 또는 목록에 연결된 목록 요소로 목록의 재귀 적 정의에 해당합니다. 따라서 요소가없는 목록은로 표시됩니다 nil. 이 빈 목록은 목록 monoid의 ID입니다.

목록을 사용하여 집합을 나타낼 수 있으므로이 경우 빈 집합도로 나타낼 수 있습니다 nil.

따라서 nil역사적으로 특별한 포인터 값 이었지만 목록이나 세트와 같은 다른 추상 영역에 대한 특수한 ID 값으로 이해되었습니다.

와 같은 포인터 nil는 널 포인터였으며, 널 (null)은 실질적인 것이 아닌 형용사 (즉, 명사)입니다.

형용사와 명사로서 두 단어를 함께 사용하는 것은 다른 관행과 상당히 일치합니다. 한정자 null 은 종종 monoid : null element 와 같은 대수 구조의 0에 사용됩니다 . 리스트는 monoid를 형성하며 , 여기서 nil 값은 ID입니다. 집합에 대해서도 마찬가지입니다 (많은 속성을 가진 대수를 형성하지만). 마찬가지로 0이되면 정수도 null 이라고합니다.

프로그래밍 언어의 저자와 특유성에 따라이 단어를 다른 단어로 사용하는 데에는 여러 가지가 있습니다.

위에서 설명한 두 가지 주요 의미는입니다 .

  • 실제로 사용 가능한 값이 없음을 나타내는 표준 "정의되지 않은 값"으로

  • 일부 도메인의 정체성 가치

이것은 NIL이 " 정답 "에서 Gilles에 의해 수행 된 " 값 없음"을 나타내는 값 이라고 주장하는 것이 정확하지 않음을 보여줍니다 . 언어와 용도에 따라 다릅니다. 프로그래밍 언어 LISP는 아마 오십오년 전 프로그래밍 용어로 NIL 소개했다. LISP 에서 빈 목록이며 빈 목록 의 자연스러운 표현 인 것과 동일하게 주목할 수 있습니다 .NIL()값이 없음을 나타내지 않습니다. 결 측값에 대한 자리 표시 자로 사용되는 경우도 있지만 빈 목록이 값이기 때문에 종종 피해야합니다. 프로그래머가 선택한 임의의 객체에서 구조에서 누락 된 값을 의미하며 허용 가능한 값과 혼동 될 수 없습니다.

두 개념은 서로 관련 될 수 있음을 위에서 보여 주었음에도 불구하고 다소 다릅니다. Gilles'answer에서 열거 한 용어 사용에 대한 자세한 분류법을 사용하여 이러한 각 단어의 사용이 하나의 의미 또는 다른 의미로 향하는 지 여부를 확인하는 것이 흥미로울 수 있습니다.

이름은 담론을 정의하는 사람에 의해 주어진 맥락에서 의미가 부여 된 것 이상입니다. 어떤 용도는 더 흔하고 자연 스럽거나 일관성이 있지만, 항상 정의를 확인하고 각 맥락에서 어떤 의미가 의도되었는지 확인해야합니다. 그리고 용어가 취향이나 일관성으로 선택되었다고 항상 기 대해서는 안됩니다.


0

NIL은 프로그래머에게 개체가 유효하지 않음을 알려주는 값을 가진 개체입니다. NULL이 0으로 정의 된 C ++에서 특히 유용합니다. C ++에서 NULL을 역 참조하면 정의되지 않은 동작이 발생합니다. NIL (정의 된 빈 객체에 대한 포인터)을 역 참조하면, 데이터 구조의 끝을 넘어서는 객체를 얻을 수 있습니다. 치명적인 프로그램 오류를 방지하고 오류를 감지하는 데 유용합니다.

이중 연결 목록과 같은 경우 NIL을 사용하여 머리와 꼬리를 모두 추적하는 목록의 시작과 끝이어야하며-> next 및-> prev 포인터가 NULL을 역 참조하지 않도록해야합니다.


내가 볼 수있는 한, 이것은 단순히 잘못되었습니다. C ++에는 "NIL"이 없습니다 .
David Richerby

1
내 대답을 잘못 해석했다고 생각합니다. 제공 한 링크는 내 답변과 상관이 없습니다. 나는 nil이 클래스별로 비어있는 (그러나 유효한) 객체를 가리 키도록 클래스별로 정의 된 사용자 정의 객체라고 제안했습니다.
abastion

"NIL 객체로 정의 할 수 있습니다"라고 말하는 대신 "NIL 객체"(내 강조)라고 쓰는 방식은 프로그래밍 스타일이 아니라 언어 기능을 설명하는 것처럼 보입니다. 그러나 당신의 대답이 순전히 프로그래밍 스타일에 관한 것이라면, 여기서 실제로 주제가 아닙니다.
David Richerby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.