C++ 字符串文字中的符号 \0 是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4711449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:14:35  来源:igfitidea点击:

What does the symbol \0 mean in a string-literal?

c++cstringescapingstring-literals

提问by UmmaGumma

Consider following code:

考虑以下代码:

char str[] = "Hello
char str[6] = "Hello
char str[] = "Hello
$ cat junk.c
#include <stdio.h>

char* string = "Hello
.LC0:
    .string "Hello"
    .string ""
"; int main(int argv, char** argc) { printf("-->%s<--\n", string); } $ gcc -S junk.c $ cat junk.s
"; /* sizeof == 7, Explicit + Implicit NUL */ char str[5]= "Hello
.LC1:
    .string "-->%s<--\n"
"; /* sizeof == 5, str is "Hello" with no NUL (no longer a C-string, just an array of char). This may trigger compiler warning */ char str[6]= "Hello
int main() {
  char str[] = "Hello
char str[]= "Hello
48 65 6C 6C 6F 00 00
H  e  l  l  o  
char str[40];
54 68 69 73 20 69 73 20 6a 75 73 74 20 61 20 70 72 69 6e 74
69 6e 67 20 74 65 73 74 00 00 00 00 00 00 00 00 00 00 00 00
";
"; int length = sizeof str / sizeof str[0]; // "sizeof array" is the bytes for the whole array (must use a real array, not // a pointer), divide by "sizeof array[0]" (sometimes sizeof *array is used) // to get the number of items in the array printf("array length: %d\n", length); printf("last 3 bytes: %02x %02x %02x\n", str[length - 3], str[length - 2], str[length - 1]); return 0; }
"; /* sizeof == 6, Explicit NUL only */ char str[7]= "Hello
48 65 6c 6c 6f 00 73 20 6a 75 73 74 20 61 20 70 72 69 6e 74
69 6e 67 20 74 65 73 74 00 00 00 00 00 00 00 00 00 00 00 00
"; /* sizeof == 7, Explicit + Implicit NUL */ char str[8]= "Hello##代码##"; /* sizeof == 8, Explicit + two Implicit NUL */
"; // strlen(str) = 5, sizeof(str) = 6 (with one NUL) char str[7] = "Hello##代码##"; // strlen(str) = 5, sizeof(str) = 7 (with two NULs) char str[8] = "Hello##代码##"; // strlen(str) = 5, sizeof(str) = 8 (with three NULs per C99 6.7.8.21)
";

What is the length of str array, and with how much 0s it is ending?

str 数组的长度是多少,以多少 0 结尾?

回答by bdonlan

sizeof stris 7 - five bytes for the "Hello" text, plus the explicit NUL terminator, plus the implicit NUL terminator.

sizeof str是 7 - “Hello”文本的五个字节,加上显式 NUL 终止符,以及隐式 NUL 终止符。

strlen(str)is 5 - the five "Hello" bytes only.

strlen(str)是 5 - 仅五个“Hello”字节。

The key here is that the implicit nul terminator is alwaysadded - even if the string literal just happens to end with \0. Of course, strlenjust stops at the first \0- it can't tell the difference.

这里的关键是始终添加隐式 nul 终止符- 即使字符串文字恰好以\0. 当然,strlen只是停在第一个\0- 它无法区分。

There is one exception to the implicit NUL terminator rule - if you explicitly specify the array size, the string will be truncated to fit:

隐式 NUL 终止符规则有一个例外 - 如果您明确指定数组大小,字符串将被截断以适应:

##代码##

This is, however, rarely useful, and prone to miscalculating the string length and ending up with an unterminated string. It is also forbidden in C++.

然而,这很少有用,并且容易错误地计算字符串长度并以未终止的字符串结束。在 C++ 中也是禁止的。

回答by SiegeX

The length of the array is 7, the NUL character \0still counts as a character and the string is still terminated with an implicit \0

数组的长度为7,NUL字符\0仍然算作一个字符,字符串仍然以隐式结尾\0

See this linkto see a working example

请参阅此链接以查看工作示例

Note that had you declared stras char str[6]= "Hello\0";the length would be 6 because the implicit NUL is only added if it can fit (which it can't in this example.)

那你已经宣布注strchar str[6]= "Hello\0";长度是6,因为隐含NUL仅添加如果它能够适应(它不能在这个例子中)。

§ 6.7.8/p14
An array of character type may be initialized by a character string literal, optionally enclosed in braces. Sucessive characters of the character string literal (including the terminating null character if there is roomor if the array is of unknown size) initialize the elements of the array.

§ 6.7.8/p14
字符类型的数组可以由字符串文字初始化,可选地用大括号括起来。字符串文字的连续字符(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。

Examples

例子

##代码##

回答by YongHao Hu

Specifically, I want to mention one situation, by which you may confuse.

具体来说,我想提到一种情况,您可能会对此感到困惑。

What is the difference between "\0" and ""?

“\0”和“”有什么区别?

The answer is that "\0"represents in array is {0 0}and ""is {0}.

答案是"\0"在数组中表示的是 is{0 0}""is {0}

Because "\0"is still a string literal and it will also add "\0"at the end of it. And ""is empty but also add "\0".

因为"\0"仍然是一个字符串文字,它也会"\0"在它的末尾添加。而且""是空还要加"\0"

Understanding of this will help you understand "\0"deeply.

了解这一点将有助于您深入了解"\0"

回答by JUST MY correct OPINION

Banging my usual drum solo of JUST TRY IT, here's how you can answer questions like that in the future:

敲击我常用的JUST TRY IT鼓独奏,以下是您将来如何回答此类问题的方法:

##代码##

... eliding the unnecessary parts ...

... 省略不必要的部分 ...

##代码##

...

...

##代码##

...

...

Note here how the string I used for printf is just "-->%s<---\n"while the global string is in two parts: "Hello"and "". The GNU assembler also terminates strings with an implicit NULcharacter, so the fact that the first string (.LC0) is in those two parts indicates that there are two NULs. The string is thus 7 bytes long. Generally if you really want to know what your compiler is doing with a certain hunk of code, isolate it in a dummy example like this and see what it's doing using -S(for GNU -- MSVC has a flag too for assembler output but I don't know it off-hand). You'll learn a lot about how your code works (or fails to work as the case may be) and you'll get an answer quickly that is 100% guaranteed to match the tools and environment you're working in.

请注意,我用于 printf"-->%s<---\n"的字符串是如何在全局字符串分为两部分时使用的:"Hello""". GNU 汇编器还以隐式NUL字符终止字符串,因此第一个字符串 (.LC0) 在这两部分中的事实表明有两个NULs。因此该字符串有 7 个字节长。通常,如果您真的想知道您的编译器正在使用某个代码块做什么,请将它隔离在一个像这样的虚拟示例中并查看它正在使用的内容-S(对于 GNU - MSVC 也有一个用于汇编器输出的标志,但我没有)不知道它的手)。您将学到很多关于您的代码如何工作(或无法工作,视情况而定)的知识,并且您将很快得到一个 100% 保证与您正在使用的工具和环境相匹配的答案。

回答by Fred Nurk

What is the length of str array, and with how much 0s it is ending?

str 数组的长度是多少,以多少 0 结尾?

Let's find out:

让我们来了解一下:

##代码##

回答by L. Lopez

##代码##

That would be 7 bytes.

那将是 7 个字节。

In memory it'd be:

在内存中它会是:

##代码##

Edit:

编辑:

  • What does the \0 symbol mean in a C string?
    It's the "end" of a string. A null character. In memory, it's actually a Zero. Usually functions that handle char arrays look for this character, as this is the end of the message. I'll put an example at the end.

  • What is the length of str array? (Answered before the edit part)
    7

  • and with how much 0s it is ending?
    You array has two "spaces" with zero; str[5]=str[6]='\0'=0

  • C 字符串中的 \0 符号是什么意思?
    它是字符串的“结束”。一个空字符。在内存中,它实际上是一个零。通常处理字符数组的函数会查找这个字符,因为这是消息的结尾。我会在最后放一个例子。

  • str数组的长度是多少?(编辑部分前已回答)
    7

  • 它以多少个 0 结束?
    你的数组有两个零的“空格”;str[5]=str[6]='\0'=0

Extra example:
Let's assume you have a function that prints the content of that text array. You could define it as:

额外示例:
假设您有一个函数可以打印该文本数组的内容。您可以将其定义为:

##代码##

Now, you could change the content of that array (I won't get into details on how to), so that it contains the message: "This is just a printing test" In memory, you should have something like:

现在,您可以更改该数组的内容(我不会详细介绍如何更改),使其包含以下消息:“这只是一个打印测试” 在内存中,您应该有类似的内容:

##代码##

So you print that char array. And then you want a new message. Let's say just "Hello"

所以你打印那个字符数组。然后你想要一条新消息。让我们只说“你好”

##代码##

Notice the 00 on str[5]. That's how the print function will know how much it actually needs to send, despite the actual longitude of the vector and the whole content.

注意 str[5] 上的 00。这就是打印功能如何知道它实际需要发送多少,尽管矢量和整个内容的实际经度。