Array of char* should end at '\\0' or “\\0

2019-02-06 09:36发布

问题:

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?

回答1:

I would end it with NULL. Why? Because you can't do either of these:

array[index] == '\0'
array[index] == "\0"

The first one is comparing a char * to a char, which is not what you want. You would have to do this:

array[index][0] == '\0'

The second one doesn't even work. You're comparing a char * to a char *, 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 the strcmp() function, because C has no built-in support for strings outside of a few (and I mean few) syntactic niceties. Whereas the following:

array[index] == NULL

Works just fine and conveys your point.



回答2:

According to the C99 spec,

  • NULL expands to a null pointer constant, which is not required to be, but typically is of type void *
  • '\0' is a character constant; character constants are of type int, so it's equivalen to plain 0
  • "\0" is a null-terminated string literal and equivalent to the compound literal (char [2]){ 0, 0 }

NULL, '\0' and 0 are all null pointer constants, so they'll all yield null pointers on conversion, whereas "\0" yields a non-null char * (which should be treated as const 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' or sizeof foo - sizeof foo + (int)0.0), you should use NULL to make your intentions clear.



回答3:

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

char* array[] = { "abc", "def", NULL };

and you test for array[index]==NULL. The proper way to test for the second one is array[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.



回答4:

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.



回答5:

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.



回答6:

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.



标签: c pointers null