답변:
여기서 명시 적으로 언급하지 않은 대부분의 대답은 null 포인터 는 실행 중에 존재하는 값이고 null 포인터 상수 는 C 소스 코드에 존재하는 구문 구조입니다.
NULL 포인터 상수 Karlson의 답변이 제대로 상태로, 하나의 값 0 (a 간단한와 정수 상수 표현이다 0
가장 흔한 예이다), 또는 그러한 발현 캐스트 void*
(예 (void*)0
).
NULL
매크로 <stddef.h>
는 구현 표준 널 포인터 상수로 확장 되는 매크로 및 기타 여러 표준 헤더로 정의 됩니다 . 확장은 일반적으로 0
또는 ((void*)0)
다른 언어 규칙을 충족시키기 위해 외부 괄호가 필요합니다.
따라서 리터럴 0
은 포인터 유형의 표현식이 필요한 컨텍스트에서 사용될 때 항상null pointer
객체를 가리 키지 않는 고유 포인터 값으로 평가됩니다 . 그것은 널 포인터 의 표현에 대해 아무 것도 암시 하지 않습니다 . 널 포인터는 일반적으로 모두 0으로 표시되지만 아무 것도 표시 할 수 있습니다. 그러나 널 포인터로 표현 된 경우에도 , 또는 아직도이다 널 포인터 상수 .0xDEADBEEF
0
(void*)0
stackoverflow 에 관한 질문에 대한 대답 은 이것을 잘 다루고 있습니다.
이것은 다른 것들 사이에, 의미 memset()
또는 calloc()
모든 비트 제로에 메모리의 영역을 설정할 수 있습니다, 반드시 널 포인터에 그 지역에있는 포인터를 설정하지 않습니다. 대부분의 구현에서 그렇게 할 가능성이 있지만 언어가 보장하지는 않습니다.
이 질문의 중복으로 간주되지 않는 이유를 모르겠어요 이 하나 , 또는 여기 화제의 방법에 대해 설명합니다.
NULL
, 또는 null 포인터 상수를 할당하면 해당 객체의 값이 null 포인터로 설정 됩니다. 머신 레벨에서 유효한 메모리 덩어리를 가리킬 수 있습니다. 널 포인터를 역 참조하면 동작이 정의되지 않습니다. 주소에서 메모리 청크에 액세스하는 0x0000000
것은 문자 그대로 다른 것과 마찬가지로 유효한 동작입니다. 이 주소는 NULL
(a)와 같음 비교 및 (b) C 객체에 대한 포인터와 같지 않은 비교를 통해 다른 주소와 다릅니다 . 널 포인터는 아무 것도 가리 키지 않음을 나타내는 데 사용되는 임의의 포인터 값입니다.
모든 플랫폼은 원하는대로 NULL을 자유롭게 정의 할 수 있습니다.
C 표준에 따르면 포인터에 0을 할당하면 해당 플랫폼의 경우 NULL 값으로 변환됩니다. 그러나 NULL 포인터를 가져 와서 int로 캐스팅하면 0을 얻을 것이라는 보장이 없습니다. 모든 플랫폼에서 그러나 사실 대부분의 플랫폼에서는 0이 될 것입니다.
해당 언어 에 대한 정보는 C 언어 사양 에서 찾을 수 있습니다 . 보증 할 수없는 한 가지 출처는 다음과 같습니다. http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
NULL pointer constant
있습니다. 내가 아는 한, 거기에는 컴파일러가 없습니다.
NULL
확장 해야하는 매크로 의 정의간에 혼동이 있습니다 . 왜냐하면 이것이 "널 포인터 상수"이기 때문입니다. 0
0
(void *)0
동일하지 않은 머신 주소가 없기 때문에 C 언어로 정의 됩니다. 그렇다면 추상화가 필요하지 않습니다! 대부분의 플랫폼에서 NULL은 결국 어떤 유형의 0 또는 다른 유형으로 구현 될 수 있지만 이식성에 관심이 있다면 이것이 보편적이라고 가정하는 것은 잘못입니다.
C 표준 문서 섹션 에 따르면 6.3.2.3
:
값이 0 인 정수 상수 표현식 또는 void * 유형으로 캐스트되는 표현식을 널 포인터 상수라고합니다 .55) 널 포인터 상수가 포인터 유형으로 변환되면 결과 포인터 (널 포인터)는 다음과 같습니다. 객체 또는 함수에 대한 포인터와 같지 않은 비교를 보장합니다.
지금까지 나는 이것에서 벗어난 컴파일러를 보지 못했습니다.