malloc(), bzero() 등의 C언어 내장함수를 공부하면서 NULL, 0, NUL, '\0'을 접하게 된다.
공통점과 차이점을 정확하게 정리하고자 한다.
우선 NULL과 NUL은 구분되며,
비교항목을 NULL, 0 과 NUL, '\0' 과 undefined 로 나눌 수 있다.
NULL, 0 비교
NULL은 널 포인터로서, (void *)0을 가리킨다.
NULL 매크로는 <stdio.h>, <stdlib.h> 등 여러 헤더파일에서 이미 정의돼있다.
C언어에서 pointer와 정수는 서로 형 변환될 수 있는데, 두 데이터 타입 모두 4byte다.
Null pointer는 정수 0으로 변환될 수 있고, 정수 0은 Null pointer로 변환될 수 있다.
즉, Null pointer는 메모리 주소 0을 가르키는 pointer라는 뜻이다. 0번지는 일반적으로 접근할 수 없는 메모리 영역이다.
따라서 pointer가 아무것도 가르키지 않을 때 Null pointer로 초기화 한다.
NULL | 0 | |
Definition | - 널 포인터 0x00000000 - '값이 없다', '비어있다'를 의미한다. - 정의되었지만 가리키는 것이 없다. |
정수 0 |
Data Type | pointer (void *)0 | int |
Type Conversion | - 서로 형 변환 가능하다. - 의도적인 차이일 뿐 물리적으로 동일하다. (afx.h에 NULL이 0으로 #define 되어있다.) |
|
Considerations | - 아무것도 가르키지 않을 때, 포인터 변수를 초기화 할 때 사용한다. - pointer를 인수로 받는 함수에서 Null pointer에 대한 해석은 함수마다 다를 수 있다. - free()처럼 Null pointer를 받아들일 경우 아무 동작도 하지 않는 함수도 있으며, 어떤 함수는 Null pointer를 받아들이면 오류가 발생할 수도 있다. |
NUL과 '\0' 비교
NUL과 '\0'은 같다.
ASCII Code표의 매핑 규칙에 따르면 0을 문자로 표기한 것이 NUL 문자다.
NUL | '\0' | |
Definition | - 문자상수 - ASCII Code의 첫 번째 문자 0 |
|
Data Type | char | |
Type Conversion |
동일한 타입이다. | |
Considerations | 문자열은 항상 NUL로 끝나야 한다. NUL을 만나기 전까지의 문자들을 문자열이라고 한다. |
한눈에 보기 위해 코드로 확인해보았다.
#include <stdio.h>
int main(void)
{
int int_n1 = 0; // 1. ASCII 0 (decimal)
char char_n1 = 0; // 2. ASCII 0 (decimal)
char char_n2 = '0'; // 3. ASCII 48 (decimal)
char char_n3 = '\0'; // 4. ASCII 0 (decimal)
char *char_n4 = 0; // 5. ASCII 0 (decimal)
char *char_n5 = ""; // 6. Empty string
char *char_n6 = '\0'; // 7. ASCII 0 (decimal)
char *char_n7 = NULL; // 8. NULL pointer
printf("====content print====\n");
printf("content of int_n1 : %d\n", int_n1);
printf("\n");
printf("content of char_n1 : %c\n", char_n1);
printf("content of char_n2 : %c\n", char_n2);
printf("content of char_n3 : %c\n", char_n3);
printf("\n");
printf("content of char_n4 : %s\n", char_n4);
printf("content of char_n5 : %s\n", char_n5);
printf("content of char_n6 : %s\n", char_n6);
printf("content of char_n7 : %s\n", char_n7);
return (0);
}
0을 int(4byte)로 출력하면 0이 출력되지만, char(1byte)로 출력하면 아무것도 출력되지 않는다.
문자에 매핑한 0은 ASCII Code에 따라 NUL 문자가 되기 때문이다.
한편 포인터 변수에 0을 넣으면 NULL pointer을 넣은 것과 동일해진다.
5. 6. 7.은 Empty string이다. (Empty string에 대한 설명글을 참고하자.)
따라서 위 코드의 출력 결과는 아래와 같다.
// 출력 결과
====content print====
content of int_n1 : 0
content of char_n1 :
content of char_n2 : 0
content of char_n3 :
content of char_n4 : (null)
content of char_n5 :
content of char_n6 : (null)
content of char_n7 : (null)
ASCII Code의 0에 해당하는 NUL은 문자열의 끝을 나타낼 때 사용한다.
이전에 ASCII Code에 대해 포스팅한 바 있으니, 이 글에서 더 자세히 읽어볼 수 있다.
undefined
아예 정의된 적 조차 없는 변수를 의미한다.
출처
aha 프로그래밍 질문 www.a-ha.io/questions/4a4a637b673cf60bb8a5d1e445870f6f
블로그 <shovelman>, "[삽잡이] 0, NULL, \0?", blog.shovelman.dev/468
자주 묻는 C언어 질문들 c-faq.com/
ASCII 코드 테이블
블로그 <오뇽>, "ASCII Table - 아스키 코드표", shaeod.tistory.com/228
'Code > C' 카테고리의 다른 글
[C언어] 데이터 타입 비교 - int, unsigned int, size_t (0) | 2020.10.07 |
---|---|
[C언어] 내장함수 비교 - strdup, malloc, calloc, free (2) | 2020.10.07 |
[C언어] 내장함수 비교 - memset, bzero (0) | 2020.10.06 |
[C언어] 내장함수 비교 - strlcpy, strlcat (0) | 2020.10.01 |
[C언어] 내장함수 비교 - strcpy, strncpy, strlcpy (0) | 2020.10.01 |
댓글