用花括号初始化 C 语言的字符数组,可以省略空字符 '\0' 吗?

4

我读到:

char pattern[] = "ould";

基本上是写成:

char pattern[] = { 'o', 'u', 'l', 'd', '\0' };

我知道空字符 \0 标记了字符串的结尾,但如果我这样写会怎么样:

char pattern[] = { 'o', 'u', 'l', 'd'};(没有 \0)

它仍然可以编译。

如果没有 \0pattern 会在哪些情况下引起问题呢?因为它似乎能够编译而没有警告 (-Wall)。

8个回答

12
如果你省略了结尾的零,那么你就不再拥有一个以零结尾的字符串,而是一个char数组,所以将其传递给任何期望一个字符串的函数都会导致错误。例如:strlen,作为strcpy的源参数,作为带有%s格式说明符的printf...参数等。

2
啊,所以\0会使字符数组成为C字符串?(我是C的新手) - user225312
1
@AA:是的,在C标准中,_string_被定义为以及包括第一个空字符终止的连续字符序列。 - CB Bailey
1
@A,没错。数组只是一系列的东西,但你需要知道数组的长度才能安全地使用它。对于字符串来说,通常使用终止符\0,这样你就不必传递长度了。这只是一个约定,但许多库函数都广泛遵守,无论是标准库还是第三方库。 - Sergei Tachenov

3
这种做法有什么问题吗?拥有没有结尾'\0'的char数组是完全有效的。它只是一个数组。'\0'存在的唯一原因是为了分隔字符串。如果您知道长度,就不需要它!
Char数组并不比其他数组特殊。您只需要'\0'来使用标准字符串函数。

2

这不是编译器警告,而是逻辑警告。如果你在使用strcpy时没有加上\0,你可能会破坏你的堆栈。


2

在编译器方面,这不会造成问题。但是,在许多函数(如printf)中,假设当您通过%s格式说明符传入某些内容时,它将以'\0'结尾,这是可能会引起问题的。

但是,如果您仅将该数组传递到您编写的函数中,或者在其中将数组长度作为单独的参数传递,并且它们都知道其长度,则不会引起问题。


2
char string[] = "abcd"; /*is valid at the end is the \0, 5 chars were allocated*/

char str[3] = {'\0'}; /* all are \0 */

strncpy(str, string, 2); /*strcpy doesn't add \0*/

str[3] = '\0'; /* now is everything fine! */

你的意思是 str[2] = '\0';。str有足够的空间容纳3个字节,而你正在尝试将其第4个字节设置为0。 - pmg
仅仅“提出想法”是不够的。请修改你的答案,确保它不会引发未定义行为,这种行为绝对不是“好”的。 - Jim Balter

1

如果你把它当作字符串处理,那就会出现问题。例如,使用strcmp、strcpy、printf等函数时,它们都期望找到空字符终止符,因此肯定会遇到问题。

只要你始终将其视为字符数组,那么普通的字符数组就没问题了。例如:

char c = pattern[2];

1

当然它可以编译——这是一个有效的C程序。问题会出现在你试图将字符数组传递给期望以空字符'\0'结尾的字符串(即字符数组)的函数时。


1
例如,获取字符串的长度将产生不可预测的结果。
strlen(pattern)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接