为什么C中的字符串需要以null结尾?

时间:2010-02-08 11:49:21

标签: c string null-terminated

只是想知道为什么会这样。我渴望了解更多关于低级语言的知识,而且我只关注C的基础知识,这已经让我感到困惑。

像PHP这样的语言会在解释和/或解析时自动为null终止字符串吗?

9 个答案:

答案 0 :(得分:28)

来自Joel's excellent article on the topic:

  

记住字符串在C中的工作方式:它们由一串字节后跟一个空字符组成,其值为0.这有两个明显的含义:

     

无法知道字符串的结束位置(即字符串长度),而无需移动它,在末尾查找空字符。   您的字符串中不能包含任何零。因此,您无法在C字符串中存储任意二进制blob,如JPEG图片。   为什么C字符串以这种方式工作?这是因为发明了UNIX和C编程语言的PDP-7微处理器具有ASCIZ字符串类型。 ASCIZ的意思是“最后用Z(零)的ASCII”。

     

这是存储字符串的唯一方法吗?不,实际上,这是存储字符串的最糟糕方式之一。对于非平凡的程序,API,操作系统,类库,您应该避免像瘟疫这样的ASCIZ字符串。

答案 1 :(得分:7)

C字符串是字符数组,C数组只是指向内存位置的指针,它是数组的 start 位置。但也必须以某种方式表达数组的 length (或end);在字符串的情况下,使用空终止。另一种选择是以某种方式携带字符串的长度与存储器指针一起,或者将长度放在第一个数组位置,或者其他什么。这只是一个惯例问题。

像Java或PHP这样的高级语言会自动存储数组的大小信息。透明,所以用户不必担心它们。

答案 2 :(得分:5)

C本身没有字符串的概念。字符串 只是字符数组(或unicode等的wchars)。

由于这些事实,C无法检查字符串的长度,因为没有“mystring->长度”,因此在某处没有设置长度值。找到字符串结尾的唯一方法是迭代它并检查\ 0。

C的字符串库使用

这样的结构
struct string {
    int length;
    char *data;
};

不需要\ 0-termination,但这不是标准C。

C ++,PHP,Perl等语言都有自己的内部字符串库,它们通常具有单独的长度字段,可以加速某些字符串函数并消除对\ 0的需要。

其他一些语言(如Pascal)使用一种被称为(令人惊讶的)Pascal String的字符串类型,它将长度存储在字符串的第一个字节中,这就是为什么这些字符串限制为255个字符的长度的原因。

答案 3 :(得分:4)

因为在C字符串中只是一个字符序列访问viua指向第一个字符的指针。

指针中没有空间来存储长度,因此您需要指示字符串结尾的位置。

在C中,决定用空字符表示。

例如,在pascal中,字符串的长度记录在指针前面的字节中,因此pascal字符串的最大长度为255个字符。

答案 4 :(得分:4)

考虑一下内存是什么:一个连续的字节大小的单元块,可以用任何位模式填充。

2a c6 90 f6

字符只是其中一种位模式。它作为字符串的含义由如何决定。如果您查看内存的相同部分,但使用整数视图(或其他类型),您将获得不同的值。

如果你有一个变量是指向内存中一串字符开头的指针,你必须知道 字符串何时结束并且下一段数据(或垃圾)开始。< / p>

实施例

让我们看看内存中的这个字符串......

H e l l o , w o r l d ! \0 
^
|
+------ Pointer to string

...我们可以看到字符串在!字符后逻辑结束。如果没有\0(或任何其他方法来确定它的结束),我们如何知道何时通过内存寻找我们已经完成该字符串?其他语言带有 string 类型的字符串长度来解决这个问题。

当我对计算机的基本知识有限时,我问了这个问题,而这个是许多年前可以帮助的答案。我希望它也可以帮助别人。 :)

答案 5 :(得分:1)

这是一种惯例 - 人们可以用另一种算法实现它(例如缓冲区开头的长度)。

在诸如汇编程序之类的“低级”语言中,很容易有效地测试“NULL”:这可能会使决定使用NULL终止字符串而不是跟踪长度计数器。

答案 6 :(得分:1)

它们需要以空值终止,以便您知道它们有多长。是的,它们只是char的数组。

像PHP这样的高级语言可能会选择隐藏空终止或根本不使用它 - 例如,它们可能会保持长度。由于涉及的开销,C不会这样做。高级语言也可能不会将字符串实现为char数组 - 例如,他们可以(有些人)将它们实现为char数组列表。

答案 7 :(得分:1)

在C字符串中,由一个连续的内存块中分配的字符数组表示,因此必须有一个指示块结尾的指示符(即空字符),或者存储长度的方式(像Pascal字符串一样,以长度为前缀。

在PHP,Perl,C#等语言中。字符串可能有也可能没有复杂的数据结构,因此您不能假设它们具有空字符。作为一个人为的例子,你可以使用一种代表字符串的语言:

class string
{
   int length;
   char[] data;
}

但您只将其视为没有长度字段的常规字符串,因为这可以通过语言的运行时环境计算,并且仅在内部由它用于正确分配和访问内存。

答案 8 :(得分:0)

它们是空终止的,因为大量的标准库函数都希望它们是。