为啥需要空终止符?

Posted

技术标签:

【中文标题】为啥需要空终止符?【英文标题】:Why is a null terminator necessary?为什么需要空终止符? 【发布时间】:2013-06-28 18:15:37 【问题描述】:

在过去的几天里,我一直在自学 C++,为我大一的 CS 专业做准备。我现在在 C 风格的字符串上,想知道空终止符的意义是什么。

我知道这是必要的,但我想我只是从根本上不明白为什么一个字符串不会只以最后一个字符结尾。

【问题讨论】:

你怎么知道最后一个字符是什么? 你需要一个同意的最后一个字符,在 C 中它是一个 0 字节。在 ASM 中,它通常是一个 $ 字符。你知道最后一个字符,但编译器怎么知道你在想什么? 【参考方案1】:

我只是从根本上不明白为什么一个字符串不会只以最后一个字符结尾。

有几种方法可以知道“最后一个字符”在哪里:

    将字符串中的字符数与字符串的字符分开存储, 放置一个指示字符串最后一个字符的标记,或者 将指向字符串最后一个字符的指针与字符串的字符分开存储。

C 选择第二条路线;其他语言(Pascal 等)选择第一条路线。 C++std::string的一些实现选择第三条路线*


* 甚至使用第一种或第三种方法的std::string 实现也会终止其缓冲区以与库的C 部分兼容。这是确保c_str() 返回有效的C 字符串所必需的。

【讨论】:

4.使所有字符串固定大小的数组,可能用空格填充。但这种疯狂只能在 fortran 中忍受。 我觉得应该提一下,即使C++string出于效率考虑一般都使用第一种(或第三种)这样就不用每次都重新计算字符串长度了需要,它仍然也使用第二种解决方案来保持字符串与 C API 兼容(假设 string 不包含空字符,这对于 C++ string 是合法的,但缩短 strlen相比string::size())。 -- 至少在调用string::c_str() 时(尽管大多数实现可能只在字符串大小更改时写入一次空终止符)。 @syam 这是一个很棒的评论,我编辑了答案以包含它。谢谢!【参考方案2】:

在 C 和 C++ 中,c 字符串存储在字符数组中。为了允许不同长度的字符串,这些数组的分配通常比它们要包含的实际字符串大得多。例如,程序员可以分配一个char[256] 数组,该数组可以保存长度介于 0 到 255 之间的字符串。但是计算机必须能够准确地知道字符串的实际长度,所以它必须以一个空字符。否则,字符数组长度必须与字符串完全相同(这是一种不切实际的解决方案,因为分配和复制内存会占用大量资源)。

【讨论】:

【参考方案3】:

因为 c 风格的字符串不知道最后一个字符是什么字符。例如,如果您正在读取一个名称,您可能会像这样创建一个缓冲区:

char buf[256] // this allows c-style strings that contain 255 characters

但是当您填充该缓冲区时,您可能不会(很可能不会)使用所有空间。如果你用“Jack”填充它,你关心的唯一信息是前五个索引,而不是全部 256。

【讨论】:

【参考方案4】:

将字符串的每个字符视为内存中的内存块。 如果一个字符串被放置在内存中。之后将另一个字符串与其相邻放置,然后计算机将认为第二个字符串连接到第一个字符串,如果不存在 null。所以,null 充当分隔符

【讨论】:

以上是关于为啥需要空终止符?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C 中的字符串需要空终止?

C memset - 优雅地添加一个空终止符

C++ char 数组空终止符位置

释放字符串直到空终止符

是 char 空终止符是不是包含在长度计数中

将 strncpy 转换为没有空终止符空间的字符串是不是安全?