【问题标题】:Why do we need a null terminator in C++ strings?为什么我们需要在 C++ 字符串中使用空终止符?
【发布时间】:2020-08-28 07:47:31
【问题描述】:

我是编程新手,对 C++ 也很陌生,最近遇到了字符串。

为什么我们需要在字符列表末尾添加一个空终止符?

我读过答案,因为我们可能不会使用数组的所有空格,因此我们需要空终止符让程序知道字符串在哪里结束,例如char[100] = "John" 但是为什么程序不能只循环遍历数组来检查填充了多少空格从而决定长度呢?

如果单词"John"在数组中只填充了四个字符,那么其他空格是什么?

【问题讨论】:

  • @S.M.关闭但没有重复的 IMO。另一个问题是关于 null 终止作为长度前缀的替代。
  • C 的作者 Dennis M Ritchie 在该问题下方给出了答案。
  • 回答“为什么程序不能检查填充了多少个空格”的问题:“检查填充了多少个空格”应该是什么意思?记忆中总是充满了一些东西。这就像在问“检查这个盒子里面是否有东西”。嗯,一个盒子里面总是有东西,即空气。而C++中的0则起到了空气的作用。

标签: c++ arrays c-strings string-literals array-initialization


【解决方案1】:

数组char john[100] = "John" 中的其他字符将用零填充,都是 空终止符。一般来说,当你初始化一个数组并且没有提供足够的元素来填充它时,剩余的元素是默认初始化的:

int foo[3] {5};           // this is {5, 0, 0}
int bar[3] {};            // this is {0, 0, 0}

char john[5] = "John";    // this is {'J', 'o', 'h', 'n', 0}
char peter[5] = "Peter";  // ERROR, initializer string too long
                          // (one null-terminator is mandatory)

另见cppreference on Array initialization。要找到这样一个字符串的长度,我们只需遍历字符直到找到0 并退出。

在 C++ 中使用空终止字符串的动机是确保与使用空终止字符串的 C 库兼容。另见What's the rationale for null terminated strings?

std::string 这样的容器不需要字符串以空字符结尾,甚至可以存储包含空字符的字符串。这是因为它们分别存储字符串的大小。但是,std::string 的字符通常以 null 结尾,因此 std::string::c_str() 不需要修改底层数组。

仅 C++ 的库很少(如果有的话)在函数之间传递 C 字符串。

【讨论】:

  • 非常感谢您的回答。但是,如果 0 是空终止符,那么当 int 数组中有 0 元素时会发生什么?
  • @NewbieToCoding int 不是char,也不是您可以从中构造字符串的东西。您可以将 int 用于数字应用程序。
  • 谢谢。根据我的阅读,空终止符是 '\0'?
  • @NewbieToCoding 是的,在 ASCII 和 UTF 字符集中,0 代表NULL 字符,表示字符串的结束。
【解决方案2】:

空终止符的存在是设计决定。它的作用是标记字符串的结尾。还有其他方法可以做到这一点,例如在 Pascal 中,字符串的第一个元素是它的大小,因此不需要空终止符。

在你给出的例子中,只有数组的前 5 个元素会被初始化,其余的都是零初始化。请注意我所说的 5 个元素,而不仅仅是 4 个。第五个元素是空终止符。

确定程序可以循环遍历字符串以找出它的长度,但它如何知道何时停止循环?

【讨论】:

  • “其余的都有垃圾值”。不,其余的都是默认初始化的,对于数字类型意味着初始化为零。见Array initialization
【解决方案3】:

nul 终止符告诉您填充了哪些空格。包括 nul 终止符在内的所有内容都已填充。之后的一切都没有。

对于 数组 的哪些元素已被填充,没有一般概念。一个数组包含一些元素;它的大小是在创建时确定的。它的所有元素最初都有一些价值。通常,无法通过查看元素的值来确定哪些已被赋值,哪些未赋值。

字符串是char 的数组一种编码约定,即字符串的“结束”由一个空字符标记。大多数字符串操作函数都依赖于这种约定。

字符串文字,例如"John",是char 的数组。 "John" 在数组中有 5 个元素:'J''o''h''n''\0'。例如,函数strcpy 会复制字符,直到它看到那个 nul 终止符:

char result[100]; // no meaningful values here
strcpy(result, "John");

调用strcpy后,result的前五个元素是'J''o''h''n''\0'。其余的数组元素没有有意义的值。

如果我没有提到这种风格的字符串来自 C,我会失职,通常被称为 C 风格的字符串。 C++ 支持所有 C 字符串的东西,但它也有一个更复杂的字符串概念,std::string,这是完全不同的。一般来说,您应该使用 C++ 风格的字符串,而不是 C 风格的字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2011-11-05
    • 2010-11-12
    • 1970-01-01
    相关资源
    最近更新 更多