( 게시물을 읽기 전에이 단락을 읽으십시오.이 게시물을 읽는 데 관심이있는 사람은이 게시물을주의 깊게 읽어야하며, 완전히 이해할 때까지 투표하지 마십시오. 감사합니다. )
이제 커뮤니티 위키이므로 누군가 개념에 동의하지 않는 경우 무엇이 잘못되었고 왜 잘못되었는지에 대한 명확하고 자세한 설명과 함께 수정하십시오. 가능하면 출처를 인용하거나 복제 할 수있는 증거를 제공하십시오.
대답
NULL == 0의 기본 요인이 될 수있는 몇 가지 다른 이유가 있습니다.
- 0은 거짓이므로
if(!my_ptr)
대신 직접 할 수 있습니다 if(my_ptr==NULL)
.
- 시작되지 않은 전역 정수는 기본적으로 모두 0으로 초기화되며 모든 0의 포인터는 초기화되지 않은 것으로 간주됩니다.
여기에 다른 답변에 대해 한 마디하고 싶습니다.
통사론 적 설탕 때문이 아니다
구문 설탕 때문에 NULL이 0이라고 말하는 것은 너무 의미가 없습니다. 그렇다면 배열의 인덱스 0을 사용하여 길이를 유지하지 않는 이유는 무엇입니까?
실제로 C는 내부 구현과 가장 유사한 언어입니다. C가 구문 설탕 때문에 0을 선택했다고 말하는 것이 합리적입니까? 그들은 0을 NULL로 매핑하는 대신 (다른 많은 언어와 마찬가지로) 키워드 null을 제공합니다!
따라서 오늘부터는 구문 설탕 일 수 있지만 C 언어 개발자의 원래 의도는 구문 설탕이 아니라는 것이 분명합니다.
1) 사양
그러나 C 사양이 상수 0에서 널 포인터 (섹션 6.3.2.3)로 말하고 구현 정의로 NULL을 정의하는 것은 사실이지만 (C11 사양의 섹션 7.19, C99 사양의 7.17) C의 발명가가 쓴 책 "The C Programming Language"에는 다음이 섹션 5.4에 명시되어 있습니다.
C는 0이 데이터에 대해 유효한 주소가 아님을 보장하므로 0의 반환 값을 사용하여 비정상 이벤트 (이 경우 공백 없음)를 알릴 수 있습니다.
포인터와 정수는 상호 교환 할 수 없습니다. 0은 유일한 예외입니다. 상수 0은 포인터에 할당 될 수 있으며 포인터는 상수 0과 비교할 수 있습니다. 기호 상수 NULL은 종종 포인터에 대한 특수 값임을 더 명확하게 나타내는 니모닉으로 0 대신 사용됩니다. NULL은에 정의되어 있습니다. 앞으로는 NULL을 사용합니다.
사람이 볼 수 있듯이 ( "제로 주소"라는 단어에서) 적어도 C 작성자의 원래 의도는 주소 0이었고 상수 0이 아니 었습니다. 또한이 발췌문에서 사양이 말하는 이유는 상수 0은 아마도 0으로 평가되는 표현식을 제외하지 않고 대신에 캐스트없이 포인터 컨텍스트에서 사용할 수있는 유일한 정수 상수 인 정수 상수 0을 포함하는 것입니다.
2) 요약
사양은 제로 주소가 제로 상수와 다르게 처리 될 수 있다고 명시 적으로 말하지는 않지만, 그렇지 않다고 말하지 않으며, 널 포인터 상수를 다룰 때 그것이 정의 된 구현이라고 주장하지 않습니다. NULL로 정의 된 상수에 의해 수행되고 대신 0이라고 주장하면 0 상수와 0 주소 사이에 차이가있을 수 있음을 보여줍니다.
(그러나 이것이 그렇다면 컴파일러가 어쨌든 모든 0 상수를 NULL로 정의 된 실제 구현으로 변환해야하기 때문에 NULL이 구현이 정의 된 이유가 궁금합니다.)
그러나 실제로는 이것을 보지 못하며 일반적인 플랫폼에서는 주소 0과 상수 0이 동일하게 취급되고 동일한 오류 메시지가 발생합니다.
게다가 오늘날의 운영 체제는 C의 NULL 포인터로 인해 제로 주소에 대한 액세스를 방지하기 위해 실제로 전체 첫 페이지 (범위 0x0000 ~ 0xFFFF)를 예약하고 있습니다 ( http://en.wikipedia.org/wiki/ 참조) . Zero_page 및 "Jeffrey Richter 및 Christophe Nasarre의 Windows Via C / C ++ (Microsoft Press에서 게시)").
따라서 실제로 실제로 본 적이 있다고 주장하는 사람에게 플랫폼과 컴파일러, 그가 실제로 수행 한 정확한 코드를 지정해달라고 요청합니다 (하지만 사양의 모호한 정의로 인해 모든 컴파일러). 플랫폼은 그가 원하는 것을 자유롭게 할 수 있습니다.)
그러나 C의 저자는 이것을 염두에 두지 않은 것 같습니다. 그리고 그들은 "0 주소"에 대해 말하고 있었고 "C는 그것이 유효한 주소가 아님을 보장합니다"뿐만 아니라 "NULL은 단지 mnemonic ", 원래 의도가"구문 설탕 "이 아니라는 것을 분명히 보여줍니다.
운영 체제 때문이 아닙니다.
또한 운영 체제가 다음과 같은 몇 가지 이유로 주소 0에 대한 액세스를 거부한다고 주장합니다.
1) C가 쓰여졌을 때이 위키 페이지 http://en.wikipedia.org/wiki/Zero_page 에서 볼 수 있듯이 그러한 제한은 없었습니다 .
2) 사실 C 컴파일러는 메모리 주소 0에 액세스했습니다.
이것은 BellLabs ( http://www.cs.bell-labs.com/who/dmr/primevalC.html ) 의 다음 논문에서 나온 사실 인 것으로 보입니다 .
두 컴파일러는 이에 대처하는 방법에있어 세부 사항이 다릅니다. 이전 버전에서는 함수 이름을 지정하여 시작을 찾습니다. 나중에 시작은 단순히 0으로 간주됩니다. 이것은 첫 번째 컴파일러가 메모리 매핑이있는 시스템을 갖기 전에 작성되었음을 나타냅니다. 따라서 프로그램의 원점은 위치 0에 없었던 반면 두 번째 시점에는 매핑을 제공하는 PDP-11이있었습니다.
(사실 오늘부터 (위키피디아와 마이크로 소프트 프레스에서 위의 참고 문헌을 인용했듯이) 제로 주소에 대한 액세스를 제한하는 이유는 C의 NULL 포인터 때문입니다! 결국에는 반대 방향으로 밝혀졌습니다!)
3) C는 운영 체제를 작성하는데도 사용되며 C 컴파일러도 사용합니다!
사실 C는 UNIX 운영 체제를 작성할 목적으로 개발되었으므로 주소 0에서 스스로를 제한해야하는 이유가 아닌 것 같습니다.
(하드웨어) 컴퓨터가 (물리적으로) 주소 0에 액세스 할 수있는 방법에 대한 설명
여기서 설명하고 싶은 또 다른 점이 있습니다. 주소 0을 참조 할 수있는 방법은 무엇입니까?
잠시 생각해 보면, 주소는 프로세서에 의해 페치 된 다음 메모리 버스의 전압으로 전송되고 메모리 시스템에서 실제 주소에 도달하는 데 사용되지만 주소가 0이면 전압이 없음을 의미합니다. , 메모리 시스템의 물리적 하드웨어가 주소 0에 어떻게 액세스합니까?
대답은 그 주소 0이 기본값이며, 즉 메모리 버스가 완전히 꺼져있을 때 메모리 시스템에서 항상 주소 0에 액세스 할 수 있으며 실제 주소를 지정하지 않고 읽기 또는 쓰기 요청을하는 것입니다. 주소가 0 인 경우) 자동으로 주소 0에 액세스합니다.
if (p != 0)
수if (p)
있지만 Java를 사용하면 습관에서 벗어나야합니다.