C 中的 '\0' 和 printf()

u_s*_*sre 21 c printf stdout c-strings

在 C 的入门课程中,我了解到,在存储字符串时,存储的字符串\0末尾带有空字符。但是,如果我想打印一个字符串,尽管printf("hello")我发现它不\0以以下语句结尾,该怎么办

printf("%d", printf("hello"));

Output: 5
Run Code Online (Sandbox Code Playgroud)

但这似乎不一致,据我所知,像字符串这样的变量存储在主内存中,我猜在打印某些内容时它也可能存储在主内存中,那么为什么会有区别呢?

dbu*_*ush 14

空字节标记字符串的结尾。它不计入字符串的长度,并且在使用 打印字符串时不会打印printf。基本上,空字节告诉进行字符串操作的函数何时停止。

char如果您创建一个用字符串初始化的数组,您会看到不同之处。使用该sizeof运算符将反映包括空字节在内的数组的大小。例如:

char str[] = "hello";
printf("len=%zu\n", strlen(str));     // prints 5
printf("size=%zu\n", sizeof(str));    // prints 6
Run Code Online (Sandbox Code Playgroud)


P__*_*J__ 8

printf返回打印的字符数。'\0'不打印 - 它只是表明该字符串中不再有字符。它也不计入字符串长度

int main()
{
    char string[] = "hello";

    printf("szieof(string) = %zu, strlen(string) = %zu\n", sizeof(string), strlen(string));
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/wYn33e

sizeof(string) = 6, strlen(string) = 5
Run Code Online (Sandbox Code Playgroud)


glg*_*lgl 6

你的假设是错误的。你的字符串确实以 结尾\0

它包含 5 个字符hello0 个字符。

“内部”print()调用输出的是打印的字符数,即 5。


Som*_*ude 6

在 C 中,所有文字字符串实际上都是字符数组,其中包括空终止符。

但是,空终止符不计入字符串(无论是否是文字)的长度,并且不会打印。当找到空终止符时打印停止。


Tsa*_*tis 6

所有答案都非常好,但我想添加另一个例子来完成所有这些

#include <stdio.h>

int main()
{
    char a_char_array[12] = "Hello world";

    printf("%s", a_char_array);
    printf("\n");

    a_char_array[4] = 0; //0 is ASCII for null terminator

    printf("%s", a_char_array);
    printf("\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于那些不想在在线 gdb 上尝试的人,输出是:

你好世界

地狱

https://linux.die.net/man/3/printf

这有助于理解逃逸终结者的作用吗?它不是字符数组或字符串的边界。这个字符会对解析的人说-停止,(打印)解析到这里。

PS:如果你将其解析并打印为字符数组

for(i=0; i<12; i++)
{
    printf("%c", a_char_array[i]);
}
printf("\n");
Run Code Online (Sandbox Code Playgroud)

你得到:

地狱世界

其中,double l 之后的空格是 null 终止符,但是,解析 char 数组时,将只是每个字节的 char 值。如果您进行另一次解析并打印每个字节的 int 值 ("%d%,char_array[i]),您将看到(您获得 ASCII 代码 int 表示形式)空白的值为 0。