Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 字符*的数组应以'\0';或\0";?_C_Pointers_Null - Fatal编程技术网

C 字符*的数组应以'\0';或\0";?

C 字符*的数组应以'\0';或\0";?,c,pointers,null,C,Pointers,Null,假设我们有一个字符指针数组 char* array[] = { "abc", "def" }; 现在到底应该放什么呢 char* array[] = { "abc", "def", '\0' }; 或 不过,这两种方法都有效。我们只需提出相应的条件来检查结束 像 或 我的问题是,哪种方法更好?大多数程序员使用哪一种 编辑 大多数答案都说NULL比“\0”和“\0”好。 但我一直认为 NULL与“\0”相同,后者与0x0或0相同 它错了吗?从技术上讲,'\0'是一个字符,而“\0”是一个字符串

假设我们有一个字符指针数组

char* array[] = { "abc", "def" };
现在到底应该放什么呢

char* array[] = { "abc", "def", '\0' };

不过,这两种方法都有效。我们只需提出相应的条件来检查结束

我的问题是,哪种方法更好?大多数程序员使用哪一种

编辑

大多数答案都说NULL比“\0”和“\0”好。 但我一直认为

NULL与“\0”相同,后者与0x0或0相同


它错了吗?

从技术上讲,
'\0'
是一个字符,而
“\0”
是一个字符串,因此,如果要检查空终止字符,则前者是正确的。但是,正如所示,您的比较在其当前形式下不起作用。

我将以
NULL
结束它。为什么?因为您不能执行以下任一操作:

array[index] == '\0'
array[index] == "\0"
第一个是比较
char*
char
,这不是您想要的。您必须这样做:

array[index][0] == '\0'
第二个甚至不起作用。您正在将
char*
char*
进行比较,是的,但是这种比较没有意义。如果两个指针指向同一块内存,则它将通过。您不能使用
==
来比较两个字符串,您必须使用
strcmp()
函数,因为C除了一些(我指的是一些)语法细节之外,没有内置的字符串支持。鉴于:

array[index] == NULL

很好地表达了您的观点。

在这两种方法中,第一种是类型错误:“\0”是字符,而不是指针。编译器仍然接受它,因为它可以将其转换为指针

第二个“有效”只是巧合。“\0”是两个字符的字符串文字。如果这些代码出现在源文件的多个位置,编译器可以(但无需)使它们相同

所以写第一个的正确方法是

char* array[] = { "abc", "def", NULL };
然后测试
数组[index]==NULL
。测试第二个的正确方法是
数组[索引][0]='\0'
;您也可以将“\0”放在字符串中(即将其拼写为
)因为它已经包含了一个空字节。

用空字符终止字符数组只是一个专门用于C中字符串的约定。您处理的是完全不同的东西——字符指针数组——因此它实际上与C字符串的约定没有关系。当然,您可以选择使用空指针终止它;这可能是指针数组的约定。还有其他方法可以做到这一点。你不能问人们它“应该”是如何工作的,因为你假设了一些不存在的约定。

根据C99规范

  • NULL
    扩展为NULL指针常量,该常量不需要,但通常为
    void*
  • “\0”
    是一个字符常量;字符常量的类型为
    int
    ,因此它与普通
    0
  • “\0”
    是一个以null结尾的字符串文字,相当于复合文字
    (char[2]){0,0}
NULL
'\0'
0
都是空指针常量,因此它们在转换时都会生成空指针,而
“\0”
生成非空的
字符*
(由于修改未定义,应将其视为
常量
);由于每次出现文字时,该指针可能不同,因此不能将其用作sentinel值


尽管您可以使用任何值为
0
的整数常量表达式作为空指针常量(例如
'\0'
sizeof foo-sizeof foo+(int)0.0
),但您应该使用
null
来明确您的意图。

空终止是一种糟糕的设计模式,最好留在历史书中。c字串后面仍然有大量的惯性,所以这是不可避免的。但是没有理由在OP的例子中使用它


不要使用任何终止符,使用sizeof(array)/sizeof(array[0])来获取元素数。

实际上,
char*
比较可能对OP有效,因为编译器统一了两个相同的字符串文字。原则上,我同意比较是没有意义的。NULL与'\0'不一样吗?我的理解是NULL='\0'==0x0。是否不正确?通常NULL为((void*)0)。。。虽然值相等,但类型不同。挑剔-第一次比较实际上是正常的-
'\0'
是一个整数值零,在此上下文中作为空指针常量进行计算。这不是一个好主意,因为它传达了作者的困惑感。如果你的意思是
NULL
,那就说
NULL
@caf正是我想写的,+1@Chris,并注意到在C中,字符文字实际上具有类型
int
而不是
char
(但这不会改变其为空指针常量的能力-
char
也是整数类型)。修复它,我也会+1u xd使用
“\0”
char*
char
进行比较,就像将苹果与桔子进行比较一样。这两种方法都不正确,真的。@Chris:using
'\0'
是将
char*
int
@Christoph进行比较,这是Chris Lutz指出的。我没有更新我的答案,而是将我的答案指向了他。我确实觉得有趣的是,这个问题有两个答案是有效的,但在技术上都不正确,而且都不起作用,因为OP认为它们是正确的。对于可变长度数组有一个约定:使用NULL作为哨兵值。虽然这是一个挑剔的问题,
NULL
仅在定义为
(void*)0
(在这种情况下,它既是空指针常量,也是空指针常量):)如果它恰好是
0
或类似的,那么它只是空指针常量,还必须转换为n
array[index][0] == '\0'
array[index] == NULL
char* array[] = { "abc", "def", NULL };