所以我读到:
char pattern[] = "ould";
基本上是更简单的写作方式:
char pattern[] = { 'o', 'u', 'l', 'd', '\0' };
我知道空字符\0
标志着字符串的结尾,但是如果我这样写会怎样:
char pattern[] = { 'o', 'u', 'l', 'd'};
(没有 \0)
它仍然编译。
哪里会有pattern
问题\0
,因为它似乎是在没有警告的情况下编译的(-Wall
)
所以我读到:
char pattern[] = "ould";
基本上是更简单的写作方式:
char pattern[] = { 'o', 'u', 'l', 'd', '\0' };
我知道空字符\0
标志着字符串的结尾,但是如果我这样写会怎样:
char pattern[] = { 'o', 'u', 'l', 'd'};
(没有 \0)
它仍然编译。
哪里会有pattern
问题\0
,因为它似乎是在没有警告的情况下编译的(-Wall
)
如果您不使用终止零,您将不再有一个以空结尾的字符串,而只是一个 数组char
,因此将其传递给任何需要字符串的函数都是错误的。例如strlen
,作为 的源参数strcpy
,作为带有格式说明符的...
参数等。printf
%s
这种行为有什么问题?最后有一个没有 '\0' 的 char 数组是完全有效的。它只是一个数组。'\0' 存在的唯一原因是分隔字符串。如果您知道长度是多少,则不需要它!
Char 数组与其他数组没有什么特别之处。您唯一需要 '\0' 的是标准字符串函数。
它不是编译器警告,而是合乎逻辑的警告。如果你strcpy
不使用\0
你可能会破坏你的堆栈。
它不会导致编译器出现问题,但会导致问题的是许多函数,例如printf
假设当您使用 %s 格式说明符传入某些内容时,它将被 '\0' 终止。
但是,如果您只是将该数组传递给您编写的函数,或者您将数组的长度作为单独的参数传递,他们都知道它有多长不会引起问题。
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! */
如果您将其视为字符串,那将是一个问题。例如,使用 strcmp、strcpy、printf。他们都期望找到空终止符,所以肯定会遇到问题。
只要您只将其视为字符数组,就可以使用普通的旧字符数组。例如
char c = pattern[2];
当然它可以编译——它是一个有效的 C 程序。如果您尝试将字符数组传递给期望以空字符结尾的字符串(以 '\0' 结尾的字符数组)的函数,则会出现问题。
例如获取字符串的长度会产生不可预知的结果。
strlen(pattern)