char *数组应该以’\ 0’或“\ 0”结尾?
让我们说我们有一个char指针数组
char* array[] = { "abc", "def" };
那到底应该放什么?
char* array[] = { "abc", "def", '\0' };
要么
char* array[] = { "abc", "def", "\0" };
虽然,两者都有效。 我们只需要对条件进行相应的检查
喜欢
array[ index ] != '\0';
要么
array[ index ] != "\0";
我的问题是哪一个更好? 大多数程序员使用哪种?
编辑
大多数答案都说NULL优于’\ 0’和“\ 0”。 但我一直都这么认为
NULL与’\ 0’相同,与0x0或0相同
这是错的吗?
我会用NULL
结束它。 为什么? 因为你不能做以下任何一种:
array[index] == '\0' array[index] == "\0"
第一个是将char *
与char
进行比较,这不是你想要的。 你必须这样做:
array[index][0] == '\0'
第二个甚至不起作用。 你将char *
与char *
进行比较,是的,但这种比较毫无意义。 如果两个指针指向同一块内存,它会通过。 你不能使用==
来比较两个字符串,你必须使用strcmp()
函数,因为C没有内置支持少数几个(我的意思是很少)语法细节的字符串。 以下内容:
array[index] == NULL
工作得很好并传达了你的观点。
根据C99规范,
-
NULL
扩展为空指针常量,这不是必需的,但通常是void *
类型 -
'\0'
是一个字符常量; 字符常量的类型为int
,因此它与plain0
-
"\0"
是以null结尾的字符串文字,等同于复合文字(char [2]){ 0, 0 }
NULL
, '\0'
和0
都是空指针常量,因此它们都将在转换时产生空指针,而"\0"
产生非空的char *
(由于修改未定义,因此应将其视为const
); 因为这个指针对于文字的每个出现可能是不同的,所以它不能用作哨兵值。
虽然您可以使用值0
任何整数常量表达式作为空指针常量(例如'\0'
或sizeof foo - sizeof foo + (int)0.0
),但您应该使用NULL
来明确您的意图。
在这两个中,第一个是类型错误:’\ 0’是一个字符,而不是一个指针。 编译器仍然接受它,因为它可以将其转换为指针。
第二个“只能巧合”。 “\ 0”是两个字符的字符串文字。 如果它们出现在源文件中的多个位置,则编译器可以(但不一定)使它们相同。
所以写第一个的正确方法是
char* array[] = { "abc", "def", NULL };
并测试array[index]==NULL
。 测试第二个的正确方法是array[index][0]=='\0'
; 您也可以删除字符串中的’\ 0’(即将其拼写为""
),因为它已经包含空字节。
好吧,技术上'\0'
是一个字符而"\0"
是一个字符串,所以如果你正在检查空终止字符,那么前者是正确的。 然而,正如Chris Lutz在他的回答中指出的那样 ,你的比较将不适用于它的当前forms。
使用空字符的字符数组的终止只是一个专门针对C中的字符串的约定。您正在处理完全不同的东西 – 一个字符指针数组 – 所以它实际上与C的约定无关字符串。 当然,你可以选择用空指针终止它; 这可能是你指针数组的惯例。 还有其他方法可以做到这一点。 你不能问人们它应该如何工作,因为你假设一些不存在的惯例。
空终止是历史书中最好留下的糟糕设计模式。 c弦背后仍有很多惯性,因此无法避免。 但是没有理由在OP的例子中使用它。
不要使用任何终结符,并使用sizeof(array)/ sizeof(array [0])来获取元素的数量。