【问题标题】:storing of strings in char arrays in C在 C 中将字符串存储在 char 数组中
【发布时间】:2010-03-24 16:00:03
【问题描述】:
#include<stdio.h>
int main()
{
  char a[5]="hello";
  puts(a);  //prints hello
}

为什么代码编译正确?我们需要六个地方来存储"hello",对吗?

【问题讨论】:

  • 可能是因为标题与问题不匹配。
  • 在我被谷歌搜索误导后修复了标题

标签: c arrays string char


【解决方案1】:

C 编译器会让你跑完数组的末尾,它不做那种检查。

【讨论】:

  • 数组在应用程序中也没有边界检查。
  • 一般来说,这是不正确的,因为 C 标准确实允许编译器在他们认为合适的时候插入检查(发生的是 undefined 行为,但这并没有意味着特定的编译器无法定义它);而且,确实,一些编译器会根据编译标志等插入数组绑定检查。
  • @eSKay,与上述相同。它们通常不会,但您的特定 C++ 编译器可能会选择插入它们,如果它们失败,则会产生实现定义的效果。
  • @Pavel:我记得我参加过一个关于设计防崩溃 C/C++ 编译器的演示文稿,以便在必须不崩溃时使用。它做了一些有趣的事情,比如通过覆盖代码中的现有内存以及对数组索引使用模运算而不是边界检查来处理内存泄漏。当在存在崩溃错误的现有程序上测试编译器时,他们发现它大部分都有效。
【解决方案2】:

C 编译器允许您明确要求不使用空终止符。

char a[] = "Hello";  /* adds a terminator implicitly */
char a[6] = "Hello"; /* adds a terminator implicitly */
char a[5] = "Hello"; /* skips it */

任何小于 5 的值都会导致错误。

至于为什么 - 一种可能性是您的字符串是固定大小的,或者被用作字节值的缓冲区。在这些情况下,您不需要空终止符。

最佳做法是使用char a[],以便编译器可以自动将其设置为正确的值(包括终止符)。

【讨论】:

    【解决方案3】:

    a 不包含空终止字符串(固定大小数组的额外初始值设定项 - 例如"hello" 中的空终止符 - 被丢弃),因此将指向该数组的指针传递给 @987654323 时的行为@ 未定义。

    【讨论】:

    • 或者更具体地说,它会编译,但是当你运行它时它会做一些奇怪的事情。
    • 这没有回答问题,这是为什么首先编译,而不是它的行为方式。
    • @Edan Maor:“固定大小数组的额外初始化器被丢弃”
    • 它可以编译,因为它是完全合法的 C++ 代码。 C++ 代码不需要工作;)
    • 我想我已经解释了错误;错误是将参数传递给puts,而不是以空结尾的字符串。 char 数组的初始化是有效的,即使是可疑的。
    【解决方案4】:

    根据我的经验,很多编译器都会让你免于编译它。不过,它通常会在运行时崩溃(因为您没有空终止符)。

    【讨论】:

    • 只有当 puts() 最终读取不属于程序的内存时才会崩溃,但如果数组之外的内存确实包含空字符,它可能不会崩溃。理解这一点很重要,因为这样的问题可能会导致分段错误,而并非每次运行程序时都会发生。
    【解决方案5】:

    仅当有空间或未指定数组尺寸时,C char 数组初始化才包含终止 null。

    【讨论】:

      【解决方案6】:

      您需要 6 个字符来将“hello”存储为以空字符结尾的字符串。但是 char 数组不限于存储以 nul 结尾的字符串,您可能需要将该数组用于其他目的,在这些情况下强制使用额外的 nul 字符将毫无意义。

      【讨论】:

        【解决方案7】:

        这是因为在 C 中,内存管理是手动完成的,不像在 java 和其他一些语言中...... 在编译期间不会检查您分配的六个位置,但如果您 必须进入归档(我的意思是实际存储)您将遇到运行时错误,因为程序在内存中为字符保留了五个位置(但预计会保留六个)但编译器没有检查!

        【讨论】:

          【解决方案8】:

          "hello" 字符串保存在只读内存中,最后为 0。 “a”指向这个字符串,这就是程序可以正常工作的原因。但我认为通常这是未定义的行为。 有必要查看编译器生成的汇编代码以了解究竟发生了什么。如果您想在这种情况下获得垃圾输出,请尝试:

          char a[5] = {'h', 'e', 'l', 'l', 'o'}

          【讨论】:

          • @Alex Farber:我仍然得到 hello 作为输出!
          • 必须在 Debug 和 Release 配置中进行测试。同样,真正的答案在汇编代码中。
          【解决方案9】:

          您使用的 C 编译器不会检查字符串文字是否适合 char 数组。您需要数组中的 6 个字符来适应文字“Hello”,因为文字包含终止零。现代编译器,例如 Visual C++ 2010 会检查这些内容并给出错误。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-02-28
            • 1970-01-01
            • 1970-01-01
            • 2014-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多