【问题标题】:Why must a char array end with a null character?为什么 char 数组必须以空字符结尾?
【发布时间】:2012-05-02 22:48:55
【问题描述】:

为什么 char array 必须以空字符结尾?是否有任何理由我必须将空字符添加到每个 char 数组?

他们似乎得到了同样的待遇。

【问题讨论】:

  • 某些语言使用长度+字符的“Pascal 风格”字符串。 C 使用 NUL。

标签: c++ c arrays char null-terminated


【解决方案1】:

通常没有理由这样做,但您必须知道,根据定义,每个字符串都是带有空终止符的char 数组。如果您的 char 数组表示一个字符串,那么如果您省略空终止符,则每个使用 C 字符串的函数都不会返回正确的值,或者会表现出与预期不同的行为。

但是charintfloatdouble 之类的类型,因此您可以随意创建char 数组,而无需它们以空值结尾。

【讨论】:

    【解决方案2】:

    在 C 语言中,如果您有一个指向数组的指针,则无法确定该数组的长度。正如@AProgrammer 指出的那样,设计人员本可以将其保留在此并迫使程序员跟踪所有字符数组的长度。但是,这会使 C 中的文本处理变得更加困难。

    因此,语言设计者确定了一个约定,允许通过指示字符串结尾的空字符的存在来推断字符串长度。

    例如,考虑strcpy

    char *strcpy(char *destination, const char *source);
    

    C 中无法确定指针destinationsource 指向的数组的长度。因此,如果不存在指示字符串结尾的标记值,则唯一的其他解决方案是传递指示source 字符串长度的额外参数。

    当然,鉴于现代安全考虑,已经引入了接收缓冲区长度参数的字符串处理函数。但是在发明空终止字符串时,计算环境看起来非常不同。

    【讨论】:

    • 是的,但是,我的意思是如果我做了 char arr[2]={'h','i'};我猜编译器知道 arr 的长度。
    • @AlexDannk 是的,这是真的。但是,如果所有字符串都被限制为相同的长度,这显然是没有用的。
    • 对不起!我没明白你的意思。您说这对于了解数组的长度很有用。但是编译器已经知道任何数组的长度。所以我觉得它没用
    • @Alex 但是您在处理文本时不使用数组。您使用指向数组的指针。然后你就不知道数组的长度了。
    • @AlexDannk:当您将该字符串传递给其他人时会发生什么?编译器无法传递数组的size;当传递给函数时,数组衰减为指针。尺寸信息丢失。
    【解决方案3】:

    char 数组不必以 null 结尾(不依赖于它的标准库函数包括 memcpymemmovestrncpy -- 错误地命名了这个最新的 --、printf使用正确的格式字符串)。

    根据定义,NUL 终止字符串 (NTCS) 需要由 NUL 终止。它是 C 标准库的字符串处理实用程序所期望的格式,也是大多数 C 程序使用的约定(在 C++ 中,通常使用 std::string

    【讨论】:

    • 所以它就像一个公约!但他们为什么会这样。让它不以空值终止再容易不过了。我不明白。我读到了,例如,当我标出一个以空结尾的数组时,编译器会知道何时停止打印。所以这个空字符在某种程度上有助于防止打印其余的垃圾字符。谢谢!
    • @Alex 在您提议的设计中,所有字符串的长度必须相同。
    • @Alex,结束标记(如 NUL)的替代方案是有一个长度字段。在实践中,使用哨兵通常会简化算法,并且它允许您不必为字符串设置任意最大大小,而无需为所有字符串支付开销(是的,当时在一个字节或两个字节大小字段之间进行选择会很难,记忆力很紧,但将自己限制在 255 个字符?我认为应该选择后者)。
    • @AlexDannk 是的,空字符的意义在于,对字符串执行某些操作的函数可以检查每个字符,当他们找到一个为空的字符时,他们知道它们位于字符串的末尾.
    【解决方案4】:

    仅当您想将其用作字符串时。然后所有 C/C++ 字符串函数将在末尾搜索空字符,如果不存在,它们将继续搜索,迟早你的应用程序会崩溃。

    如果您只打算将数组字符用作字符数组,而不是将它们称为字符串,那么没问题。它就像一个整数数组。

    【讨论】:

    • 这个怎么样。字符 arr[2]={'h','i'}; cout
    • @Alex - 它有时似乎有效,但结果确实未定义。我们不知道数组后面的下一个字节的值——它可能为零。在这种情况下,显示的值看起来不错。否则,程序可能会显示垃圾或崩溃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    相关资源
    最近更新 更多