NULL과 0과 '\0' 의 차이점...

leolo의 이미지

이런거 질문드려도 될런지..

정확하고 깊이 있게 말씀해주셨으면 합니다.

문자열 끝에 NULL이 사용하는 것이 잘못된 코딩이라고 하는데요.

널문자로 끝나야 하니까 '\0'을 입력하겠죠.

하여튼. 이들 3가지 NULL, 0, '\0' 에 대한 차이점을 자세히 부탁드립니다.

참고로 이들과 컴파일러에 따른 차이점도 있는지 알고 싶습니다.

cinsk의 이미지

C FAQs에 있는 5.13 질문을 참고하시면 됩니다.

영문판/한글판 제 서명을 참고하세요.

ㅡ,.ㅡ;;의 이미지

leolo wrote:
이런거 질문드려도 될런지..

정확하고 깊이 있게 말씀해주셨으면 합니다.

문자열 끝에 NULL이 사용하는 것이 잘못된 코딩이라고 하는데요.

널문자로 끝나야 하니까 '\0'을 입력하겠죠.

하여튼. 이들 3가지 NULL, 0, '\0' 에 대한 차이점을 자세히 부탁드립니다.

참고로 이들과 컴파일러에 따른 차이점도 있는지 알고 싶습니다.

NULL, 0, '\0' 모두 같은값이나 값이 타입이 틀리죠
컴파일러에따라 타입케스팅이 안되면 경고를 낼수 있습니다.

문자열 끝에 NULL 을 사용한다?? 물론 그런경우는 고의적인 의도가 아니라면..
잘못된경우겠죠..
전에 이런황당한것을 본적이 있습니다.
str = "어쩌고 저쩌고 마지막에\0"
스트링의 마지막에 저건머냐고 했더니.. 스트링의마지막이니 NULL 문자를 붙여줘야 되지 않냐는..ㅡㅡ;;
스트링과 코드를 혼동하고 있더군요.


----------------------------------------------------------------------------

pynoos의 이미지

참고로...

ASCII CODE 이름으로서의 NUL 과
( http://www.hyperdictionary.com/computing/ascii+character+table )

추가 2004/07/22
http://www.asciitable.com/

NULL pointer 와 null string 을 구별해서 사용해야합니다.

NUL 값은 말 그대로 '\0' 을 말하고,
NULL pointer 는 pointer로서 값이 0x00000000 을 말하며, 흔히 (void *)0 으로 선언되어 있습니다.
null string은 "" 즉, 빈 문자열이며, 흔히 길이가 1 이며 내용은 NUL 값이 하나 있는 string을 말합니다.

주로 NUL과 NULL이 발음이 같으므로 생기는 오류입니다.

kyang2의 이미지

NULL 포인터 말고두 NULL 값을 집어넣는 코딩이 있지 않나요 =ㅅ=?

개인적으로 NULL 을 넣은 스트링과

값이 '\0' 밖에 없는 스트링은 같다고 알고있는데...

신이 있다고 가정하지 않는 한, 삶의 목적에 대한 질문은 무의미하다. -B. 러셀, 철학자

Viz의 이미지

kyang2 wrote:
NULL 포인터 말고두 NULL 값을 집어넣는 코딩이 있지 않나요 =ㅅ=?

개인적으로 NULL 을 넣은 스트링과

값이 '\0' 밖에 없는 스트링은 같다고 알고있는데...

      1 #include <stdio.h>
      2
      3 int
      4 main() {
      5     if ( "" == NULL )
      6         printf("true\n");
      7     else
      8         printf("false\n");
      9     return 0;
     10 }

의 결과는 false 입니다.

엄연히 달라요~
'\0' 만인 string, 즉 ""은 '\0'이라는 값이 들어있는 주소를 가리키는 char * 인 것이지요.

My Passion for the Vision!

ㅡ,.ㅡ;;의 이미지

kyang2 wrote:
NULL 포인터 말고두 NULL 값을 집어넣는 코딩이 있지 않나요 =ㅅ=?

개인적으로 NULL 을 넣은 스트링과

값이 '\0' 밖에 없는 스트링은 같다고 알고있는데...

char str[128];

*str = NULL;

과 *str = '\0' 은 같은거 맞습니다.
물론 경고가 발생할수 있겠네요..^^ 알고 쓴다면 상관없죠머..

바로위에님은
"NULL 을 넣은 스트링과 " 이라고 했는데 NULL 그자체를 바로 비교 하셨네요..


----------------------------------------------------------------------------

cinsk의 이미지

Quote:
char str[128];

*str = NULL;

과 *str = '\0' 은 같은거 맞습니다.

다릅니다. NULL은 매크로로 정의되어 있는 것이고, 이는 결국 null pointer constant인 0이 됩니다. Null pointer constant는 코드에 쓰는 것은 integer zero인 0을 쓰지만, 실제 어떤 값이 메모리에 들어가느냐는 machine-dependent한 부분입니다. 대부분의 CPU가 실제 (all bit 0) 0을 null-pointer-constant로 쓰지만 그렇지 않은 machine도 있을 수 있습니다.

'\0'은 Code system의 0번째 문자, ASCII 시스템이라고 할 때 0번 문자 NUL을 의미합니다. 결국 char type 변수에 0이나 '\0'을 대입하는 것은 같습니다만, NULL을 대입하면 안됩니다.

ㅡ,.ㅡ;;의 이미지

cinsk wrote:

다릅니다. NULL은 매크로로 정의되어 있는 것이고, 이는 결국 null pointer constant인 0이 됩니다. Null pointer constant는 코드에 쓰는 것은 integer zero인 0을 쓰지만, 실제 어떤 값이 메모리에 들어가느냐는 machine-dependent한 부분입니다. 대부분의 CPU가 실제 (all bit 0) 0을 null-pointer-constant로 쓰지만 그렇지 않은 machine도 있을 수 있습니다.

'\0'은 Code system의 0번째 문자, ASCII 시스템이라고 할 때 0번 문자 NUL을 의미합니다. 결국 char type 변수에 0이나 '\0'을 대입하는 것은 같습니다만, NULL을 대입하면 안됩니다.

전 통상적으로 질문자의 환경에서 같을것이라 생각하고 말한건데요...
그렇게 따지면.. 결국 같은것은 아무것도 없죠.. 0 이나 '\0'도 다르게 작동할
머신이 있을수도 있기는 마찬가지죠.. 없다면제가만들어서라도..보여드릴수..^^;;

그러한 특수하거나 이상한경우가아니면 같은결과를 얻는다는 것입니다.
물론 엄격히말해서 다르다는것을 알지요..그래서 경고가발생한다고 했구요
완전히 같다면 경고가 발생할리도 없지요..


----------------------------------------------------------------------------

sangwoo의 이미지

ㅡ,.ㅡ;; wrote:
cinsk wrote:

다릅니다. NULL은 매크로로 정의되어 있는 것이고, 이는 결국 null pointer constant인 0이 됩니다. Null pointer constant는 코드에 쓰는 것은 integer zero인 0을 쓰지만, 실제 어떤 값이 메모리에 들어가느냐는 machine-dependent한 부분입니다. 대부분의 CPU가 실제 (all bit 0) 0을 null-pointer-constant로 쓰지만 그렇지 않은 machine도 있을 수 있습니다.

'\0'은 Code system의 0번째 문자, ASCII 시스템이라고 할 때 0번 문자 NUL을 의미합니다. 결국 char type 변수에 0이나 '\0'을 대입하는 것은 같습니다만, NULL을 대입하면 안됩니다.

전 통상적으로 질문자의 환경에서 같을것이라 생각하고 말한건데요...
그렇게 따지면.. 결국 같은것은 아무것도 없죠.. 0 이나 '\0'도 다르게 작동할
머신이 있을수도 있기는 마찬가지죠.. 없다면제가만들어서라도..보여드릴수..^^;;


C99표준에는 C프로그램의 작동에 사용되는 캐릭터 셋의 경우에,
'null character는 0으로 인코딩되어야 한다' 라는 조건이 있습니다. 따라서
0과 '\0' 이 다른 머신은 표준을 준수하지 않게 되죠.

----
Let's shut up and code.

moonzoo의 이미지

C에서는 lvalue가 포인터인 경우에 이 포인터를 null pointer

로 하기 위해서 우변에 0 을 씁니다.

NULL은 위의 0을 좀더 보기 좋게 표현한 것일뿐입니다.

심지어 NULL의 define값이 0이 아닐지라도 그 NULL의 역할은

위의 0과 같습니다..

'\0'은 전혀 다른 개념으로서 단지 char set의 0번째 문자일 뿐입니다.

아스키에서는 0x00 즉 모든 비트가 0이다를 나타내는 1바이트 문자일

뿐입니다. 보통 NUL 이라고 하죠.

char * ptr = 0 ; 에서 0은 숫자 0이 아닌 null pointer constant로 되지만

char * ptr = '\0'는 컴파일러나 머신에 의존적이 될 것입니다.

cinsk의 이미지

덧붙여서, 음.. 제가 표준에 정통한 사람은 아닙니다만, (혹시 틀린게 있으면 지적해주시기 바랍니다.)

'null character'는, 모든 bit가 0인 character이며, 문자열 끝을 나타내기 위해 씁니다. 일반적으로 '\0'으로 코드에서 나타냅니다. 모든 비트가 0이므로, integer 0도 character type에 대입될 경우, '\0'과 같은 뜻이 될 것입니다. ASCII 문자셋에서는 이 문자를 약어 NUL로 표기합니다.

'null pointer'는 아무 것도 가리키지 않는다고 보장되는 포인터입니다. null pointer를 코드에서 표기할 때에는 null pointer constant를 써서 나타냅니다. 실제 한 machine에서 쓰이는 null pointer가 모든 비트가 0인 값이라고 보장할 수는 없습니다.

'null pointer constant'는 integer 0 또는 void *으로 캐스팅한 integer 0을 의미하며, 이는 'null pointer'를 나타내기 위해 사용합니다.

--

덧붙여 C Programming FAQs - Steve Summit에 보면, 이런 말도 있습니다.

포인터를 쓸 자리에 0을 쓰는 것은 당연하다. integer 0은 정의에 의해 null pointer constant가 될 것이며 따라서 null pointer를 나타내기 때문이다. 그러나 printf와 같이 가변 인자를 받는 함수에서는 사정이 다르다. 왜냐하면 컴파일러가 가변 인자의 type을 알아낼 수 없기 때문에, 0이란 token을 보았을때, 이 것이 integer 0을 뜻하는 것인지, 아니면 null pointer constant 0을 뜻하는 것인지 알 수 없기 때문이다. 따라서 이런 가변 인자를 받는 함수에 null pointer를 전달하기 위해서는 "(void *)0"라고 integer 0이 아닌 null pointer constant라고 나타내는 것이 필요하다.

책 읽은 지는 오래되어 기억나는 대로 쓴 것이니, 실제 책 내용 그대로가 아님을 미리 밝힙니다.

C Programming FAQs: Question 5.13 를 읽어보시기 바랍니다.

--

실제로 얼마전에 GNU libiberty에 포함되어 있는 obstack module을 80186 계열의 CPU에 포팅한 적이 있었는데. 이 null pointer 관련해서 어려움을 겪은 게 생각납니다. ^^; segment:offset 계열에서는 segment value에 상관없이 offset이 0이면 null pointer가 되기 때문에..

whenicu의 이미지

논쟁이 너무 어렵네요 ^^;

아주 특별한 경우가 아니라면
같은 것으로 생각하시는 편이 좋을듯 합니다만.
(물론 가독성 하고도 관련있는거 같고요)

참고로 저는 0만을 사용합니다.

moonzoo의 이미지

Quote:
아주 특별한 경우가 아니라면
같은 것으로 생각하시는 편이 좋을듯 합니다만.

저를 포함해서 대부분 위에 쓰신분들이 구분하지 않고 쓰는것은

바람직하지 않다는 쪽으로 열씸히 쓴것같은데..

결론을 같은것으로 생각하시는 편이 좋다고 하시면 --;

whenicu의 이미지

헙 죄송합니다..
ㅡ..ㅡ;

익명 사용자의 이미지

#include

int main (void)
{
char *sVal = NULL;
char cVal = '\0';
int iVal = 0;

printf ("%p, %x, %s, %c, %d\n", sVal, &sVal, sVal, sVal, sVal);
printf ("%p, %x, %s, %c, %d\n", cVal, &cVal, cVal, cVal, cVal);
printf ("%p, %x, %s, %c, %d\n", iVal, &iVal, iVal, iVal, iVal);

return 0;
}

tot0ro의 이미지

이 코드의 대한 답은
(nil), 주소, (null), , 0
으로 모두 같은 값을 출력함

tot0ro의 이미지

환경은 x86 ubuntu

Taegul의 이미지

디스어셈된 코드를 셋다 모두 0인데 코딩할 때 의미를 명확히 구분하기 위해서 저렇게 하는것일거에요.

근데 널 문자 '\0' 이건 너무 입력이 불편한 듯.
집중력 떨어질 때는 실수로 \빼고 '0'이라고 입력해버리는 사태가 발생하기도 하구요.;

김정균의 이미지

한글로 "널" 이 문제가 좀 있습니다. NUL 과 NULL 이 구분이 안되요 :)
읽는 사람에 따라 다르게 해석이 가능할 것 같다는 거죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.