C 中的 '\0' 和 printf()

'\0' and printf() in C

在C的入门课程中,我了解到在存储字符串时,在其末尾存储空字符[=11=]。但是如果我想打印一个字符串,比如 printf("hello") 怎么办,尽管我发现它不以 [=11=] 结尾,通过以下语句

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

Output: 5

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

printf returns 打印的字符数。 '[=13=]' 未打印 - 它只是表示此字符串中不再有字符。它也不计入字符串长度

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

    printf("szieof(string) = %zu, strlen(string) = %zu\n", sizeof(string), strlen(string));
}

https://godbolt.org/z/wYn33e

sizeof(string) = 6, strlen(string) = 5

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

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

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

你的假设是错误的。您的字符串确实以 [=10=].

结尾

它包含5个字符hello和0个字符。

"inner" print() 调用输出的是打印的字符数,即 5。

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

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

C函数中printf() returns打印的字符数,[=12=]是一个null结束符,用来表示字符串的结束在 c 语言中,从 c++ 开始没有内置 string 类型,但是您的数组大小需要至少大于要存储的 char 的数量。

这是参考:cpp ref printf()

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

#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;
}

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

Hello world

Hell

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

这有助于理解转义终止符的作用吗?它不是 char 数组或字符串的边界。这个字符会对解析的人说 -STOP, (print) parse until here.

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

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

你得到:

Hell world

其中double l后面的空格是空终止符,但是解析char数组,将只是每个字节的char值。如果你再做一次解析并打印每个字节的 int 值 ("%d%,char_array[i]),你会看到(你得到 ASCII 代码-int 表示)空白的值为0.

But what if I wanted to print a string, say printf("hello") although I've found that that it doesn't end with [=19=] by following statement

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

Output: 5

你错了。此语句不确认字符串文字 "hello" 不以终止零字符 '[=17=]' 结尾。此语句确认函数 printf 输出字符串元素,直到遇到终止零字符。

当你在上面的语句中使用字符串文字时,编译器 创建一个具有静态存储持续时间的字符数组,其中包含字符串文字的元素。

所以实际上这个表达式

printf("hello")

由编译器处理如下

static char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '[=12=]' };
printf( string_literal_hello );

这里函数printf的作用你可以想象成下面这样

int printf( const char *string_literal )
{
    int result = 0;

    for ( ; *string_literal != '[=13=]'; ++string_literal )
    {    
        putchar( *string_literal );
        ++result;
    }

    return result;
}

要获取存储在字符串文字中的字符数 "hello" 您可以 运行 以下程序

#include <stdio.h>

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

    printf( "The size of the literal \"%s\" is %zu\n", literal, sizeof( literal ) );

    return 0;
}

程序输出为

The size of the literal "hello" is 6

你得先理清楚你的概念.. 当你处理数组时它会被清除,你正在使用的打印命令只是计算括号内的字符。它在数组字符串中必须以 \0

结尾

字符串是字符向量。包含构成 字符串,后跟特殊结束字符 字符串:'\0'

示例: char str[10] = {'H', 'e', 'l', 'l', 'o', '\0'};

示例:以下字符向量不是一个字符串,因为它没有以'\0'结尾

char str[2] = {'h', 'e'};