【问题标题】:In C++, is a string type object an array of characters just like a C-string object?在 C++ 中,字符串类型对象是否像 C 字符串对象一样是字符数组?
【发布时间】:2018-10-07 20:41:29
【问题描述】:

所以我知道所有 C 字符串都是 C++ 中的字符数组。字符串呢?

还有为什么 char x[] = {'H', 'i'}; 不是 C 字符串? x 是一个字符数组,这意味着它是一个 C 字符串。我错过了什么吗?

【问题讨论】:

  • 不,std::string 是一个类。 char x[] = {'H', 'i'}; 不是有效的 c 字符串,因为没有终止 '\0' 字符。
  • 您使用的c-strings标签的描述:“在编程语言C中,字符串表示为一个字符序列,后跟一个空终止符(表示为\0)。"
  • 您是专门询问std::string 的吗?因为在C++ 中,您可以选择以各种方式表示字符串类型对象
  • 感谢您的所有回答。但我想明确这个问题:字符串(不是 C 字符串)是 C++ 中的字符数组吗?

标签: c++ c-strings


【解决方案1】:

我刚刚在这里为您的问题找到了很好的解释:C strings and C++ strings。简而言之:

C 字符串通常声明为 char 数组。但是,char 数组本身并不是 C 字符串。有效的 C 字符串需要存在终止“空字符”(ASCII 值为 0 的字符,通常由字符文字 '\0' 表示)。

C++ 字符串是类字符串的对象,在头文件中定义,在标准命名空间中。 string 类有几个构造函数,可以调用(显式或隐式)来创建字符串对象。

内存中的表示:

C 字符串

C++ 字符串

更新:

你应该明白:

  1. C++ 提供了比 C 中的 char 更多的字符类型,例如UTF-16 和 UTF-32。

  2. C++ 定义了一个名为 std::basic_string 的东西,它是一个类模板,用于从这些字符类型中生成字符串。

  3. C++ typedef char 的类模板类型为std::string

现在,您知道std::stringbasic_string 用于char 类型的字符。参考Does std::string need to store its character in a contiguous piece of memory?,如果您提到std::string,那么对于C++ 11 和更高版本,它本质上是char 类型字符的一个数组(不是两个或更多数组)。对于C++ 11 之前的C++ 版本或对于某些其他类型的字符(实际上我不确定),底层内存可能不是连续的(即它可能需要两个或更多数组(不是一个数组)来存储字符串)。

【讨论】:

  • C++ 字符串表示在 C++ 11 之前是不正确的,因为它们不能保证在内存中连续布局,并且对于 C++ 11 及更高版本,它们保证会被 nul 终止。
  • 那么 C++ 字符串总是“字符数组”吗?还是不一定?
  • 由于“C++ 字符串表示在 C++ 11 之前不是真的,因为它们不能保证在内存中连续布局”,所以它可以由多个字符数组组成(不一定是 AN 数组) -- 这件事实际上因 C++ 版本和字符类型而异。在stackoverflow.com/questions/33124479/… 上查看更多信息。
  • 所以...我阅读了该链接上的答案...不太了解...因为我是初学者...但是您似乎是在说“某些 C++ 版本”,所有字符串都是“字符数组”,而在“某些其他 C++ 版本”中,字符串不是字符数组。对吗?
  • @NewLearner 从 C++11 开始,标准保证 std::string 的成员 data() 返回的指针指向 size() 字符,后跟 '\0'。以前没有这样的成员,成员c_str()可能返回一个副本。
【解决方案2】:

C 字符串是一个 以空结尾的字符串,因此,任何不以零结尾的字符数组都不是 C 字符串。

C 字符串为字符数组char *char []

但是关于 C++ 字符串,它是一个有很多操作(方法)可以发生在它上面的类,它有长度并且当你尝试时它会检查长度(比如 C++ vectorarray)访问它的数组下标(使用at 方法)。它的复制可能会更高效,因为分配新内存位置的长度是已知的。

您可以从 C 字符串创建 std::string。有一个构造函数接受一个 C 字符串和一个长度,并从中创建一个 std::string。

所有处理字符串的 C 函数,都将 C 字符串视为以 null 结尾,所以如果不是,C 将继续搜索最近的下一个 null,这是非常危险的。

【讨论】:

  • 当您尝试访问它的数组订阅时,它会检查长度(如 C++ vectorarray” - 不正确。只有.at() 检查有效索引。
【解决方案3】:

C++ 提供标准库形式,其中定义了class string。 String 类不仅仅是一个 C 字符串(char* C 或 char sz[])。类字符串具有方法和属性,而后者没有。类字符串的大小也会在运行时更改,而后者则不会。它还在其 Ctor 和 dtor 中为您管理内存。建议尽可能使用 Class 字符串而不是 char*。

  • Class String 在字符串末尾附加一个 NULL 字符 \0 作为字符串结尾的标志,而后者没有。

【讨论】:

    【解决方案4】:

    前面的答案提到过 char x[] = {'H', 'i'};不是有效的 C 字符串,因为没有空字符来标识字符串的终止或结尾。 C++ 标准模板提供了保证动态连续内存分配(类似于 Vector)和通过索引轻松访问的 String 类。更多信息请参见https://en.cppreference.com/w/cpp/string/basic_string

    【讨论】:

    • 来自 C++ 11 的连续内存。
    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 2016-10-24
    • 2019-03-20
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    相关资源
    最近更新 更多