Lets say we have an array of char pointers
char* array[] = { "abc", "def" };
Now what should be put in the end ?
char* array[] = { "abc", "def", '\0' };
or
char* array[] = { "abc", "def", "\0" };
Though, both works. We only have to put the condition to check the end accordingly
like
array[ index ] != '\0';
or
array[ index ] != "\0";
My question is which one is the better way? Which is used by most programmers?
Edit
Most answers say that NULL is better than '\0' and "\0". But I always thought that
NULL is same as '\0' which is same as 0x0 or 0
Is it wrong?
Of these two, the first one is a type mistake: '\0' is a character, not a pointer. The compiler still accepts it because it can convert it to a pointer.
The second one "works" only by coincidence. "\0" is a string literal of two characters. If those occur in multiple places in the source file, the compiler may, but need not, make them identical.
So the proper way to write the first one is
and you test for
array[index]==NULL
. The proper way to test for the second one isarray[index][0]=='\0'
; you may also drop the '\0' in the string (i.e. spell it as""
) since that will already include a null byte.I would end it with
NULL
. Why? Because you can't do either of these:The first one is comparing a
char *
to achar
, which is not what you want. You would have to do this:The second one doesn't even work. You're comparing a
char *
to achar *
, yes, but this comparison is meaningless. It passes if the two pointers point to the same piece of memory. You can't use==
to compare two strings, you have to use thestrcmp()
function, because C has no built-in support for strings outside of a few (and I mean few) syntactic niceties. Whereas the following:Works just fine and conveys your point.
Null termination is a bad design pattern best left in the history books. There's still plenty of inertia behind c-strings, so it can't be avoided there. But there's no reason to use it in the OP's example.
Don't use any terminator, and use sizeof(array) / sizeof(array[0]) to get the number of elements.
Well, technically
'\0'
is a character while"\0"
is a string, so if you're checking for the null termination character the former is correct. However, as Chris Lutz points out in his answer, your comparison won't work in it's current form.The termination of an array of characters with a null character is just a convention that is specifically for strings in C. You are dealing with something completely different -- an array of character pointers -- so it really has no relation to the convention for C strings. Sure, you could choose to terminate it with a null pointer; that perhaps could be your convention for arrays of pointers. There are other ways to do it. You can't ask people how it "should" work, because you're assuming some convention that isn't there.
According to the C99 spec,
NULL
expands to a null pointer constant, which is not required to be, but typically is of typevoid *
'\0'
is a character constant; character constants are of typeint
, so it's equivalen to plain0
"\0"
is a null-terminated string literal and equivalent to the compound literal(char [2]){ 0, 0 }
NULL
,'\0'
and0
are all null pointer constants, so they'll all yield null pointers on conversion, whereas"\0"
yields a non-nullchar *
(which should be treated asconst
as modification is undefined); as this pointer may be different for each occurence of the literal, it can't be used as sentinel value.Although you may use any integer constant expression of value
0
as a null pointer constant (eg'\0'
orsizeof foo - sizeof foo + (int)0.0
), you should useNULL
to make your intentions clear.