Null의 개념

a1.jpg

Understanding and Using C Pointers: Core Techniques for Memory Management 1st Edition을 읽고 정리한 내용을 기술합니다.

Understanding and Using C Pointers 정리 시리즈
  1. 포인터를 잘 알아야 하는 이유
  2. 포인터 선언하기
  3. Null의 개념
  4. void포인터와 전역, 정적포인터
  5. 포인터의 크기와 데이터 타입
  6. 일반적인 포인터 사용
  7. 동적 메모리 관리

Null의 개념

널(Null)은 매우 흥미로운 주제다. 하지만 종종 널이 가진 다양한 개념들이 잘못 이해되거나 혼란을 일으킨다. 널은 다음과 같은 개념들을 포함한다.

  • 널 개념
  • 널 포인터 상수
  • NULL 매크로
  • NUL 아스키 문자(\0)
  • 널 문자열
  • 널 문장(;)

포인터에 NULL이 할당되면 해당 포인터는 아무것도 가리키지 않음을 의미한다. 널 개념은 포인터가 다른 포인터와 다른 특별한 값을 가질 수 있음을 의미한다. 널이 할당된 포인터는 메모리의 어떤 영역도 가리키지 않으며 두 개의 널 포인터는 항상 서로 같다.

실제 널의 개념은 널 포인터 상수에 의해 지원되는 추상적 개념이다. 널 포인터 상수는 0이거나 0이 아닐 수도 있으며 C 개발자는 널 상수의 실제 내부적인 표현에 대해서 신경 쓰지 않아도 된다.

NULL 매크로는 상수 정수 0을 void포인터로 캐스팅한 것이다. 많은 라이브러리에서 다음과 같이 정의한다.

#define NULL (void *)0)

따라서 다음 두 문장은 같다.

char *ptr = NULL;
char *ptr = 0;

NUL 아스키 문자와 널 포인터

NUL(\0) 아스키 문자는 모두 0으로 채워진 바이트로 정의된다. 그러나 NUL은 널 포인터와 같지 않다. C에서 문자열은 0으로 끝나는 문자들의 연속으로 표현된다. 널 문자열은 빈 문자열이고 어떤 문자들도 포함하지 않는다. 그리고 마지막으로, 널 문장은 단일 세미콜론이 포함된 문장으로 이뤄진다.

널 포인터는 연결 리스트에서 종종 리스트의 끝을 표시하기 위해 사용되는 것처럼 많은 데이터 구조의 구현에서 매우 유용하게 사용된다.

⚠️ 널 포인터초기화되지 않은 포인터는 명백히 다르다!!

NULL을 포함한 포인터가 메모리상 어떤 위치도 참조하지 않는 것에 비해, 초기화되지 않은 포인터는 어떤 값이라도 포함될 수 있으며 참조될 수 있다.

포인터에 0 값은 할당될 수 있지만 다른 정숫값들은 할당되지 않는다.

char *ptr = 0;      // 가능
char *ptr = 100;    // error

포인터는 논리식 표현에서 단독으로 피연산자로 사용될 수 있다. 예를 들어, 아래 코드처럼 포인터가 NULL로 설정되었는지 테스트할 수 있다.

if(ptr) {
    // 널이 아닌 경우
} else {
    // 널인 경우
}

💡위 코드에서 포인터 변수 ptr이 NULL로 초기화된 상태라면 ptr의 값은 이진수 0으로 해석된다. 이진수 0은 false를 나타내므로 ptr가 NULL을 포함하고 있다면 else 구문이 실행될 것.