代码之家  ›  专栏  ›  技术社区  ›  Gqqnbig

为什么初始化char*[]需要const而字符串[]不需要const?

c++
  •  0
  • Gqqnbig  · 技术社区  · 5 年前
    char* c_arguments[] = { "hi","bye" }; //(1)
    std::string cpp_arguments[]= { "hi","bye" };
    

    (1)在C++ 17标准下Visual Studio中的错误

    E0144:不能使用const char*类型的值初始化 char类型的实体*

    如果我加上 const 一开始代码编译得很好。

    但是为什么第一行需要常量,而第二行不需要常量?

    如何创建 char*[] 没有字符串文本数组中的常量?

    代码可以使用最新的C++标准的特性,不必考虑遗留系统。

    2 回复  |  直到 5 年前
        1
  •  2
  •   Ben Voigt    5 年前

    第二行是调用复制构造函数。即使文本是只读的,副本也不是。

    要创建指向可写字符串的指针数组,必须循环并创建每个文本的副本,就像 std::string 建造师会的。

        2
  •  2
  •   tarkmeper    5 年前

    字符串是对象,在引擎盖下,编译器正在创建两个 const char* 缓冲区,然后将这些值复制到字符串对象中,以提供可变数组。你也可以这样做来创建你的 char* 如果你愿意的话。

    我不建议使用文字 字符* C++中没有const的指针。有很多方法可以把他们搞得一团糟。如果要修改字符缓冲区,应将其包装为字符串,并使用适当的库函数。

        3
  •  2
  •   Yakk - Adam Nevraumont    5 年前

    第一种类型 c_ 是指向的指针数组 char . 第二种类型 cpp_ 是一个数组 std::string S.

    当你通过 "string" 对于指针,它生成指向第一个元素的指针。但是数据的类型 "hello" const 所以 char* 不想指向它。相反,你需要一个 char const* 或指向的指针 康斯特 烧焦 S.

    对于一个 STD::字符串 ,当你通过时 “你好” 为了它,它 副本 将字符放入由 STD::字符串 . 副本可以是可变的,因此不需要 康斯特 .

    有些编译器标志放弃了对 康斯特 分配时 “你好” 字符串文本到 烧焦* 但是,它们的存在是为了与以前编写的代码兼容。 康斯特 是一件事。避免使用它们。如果在使用这些标志后意外地修改字符串常量,则会继续执行未定义的行为(很可能在使用字符串池时会导致精神错乱)。

        4
  •  1
  •   Serge    5 年前

    在C++中,基本上有原始数据类型和用户定义的数据类型。诸如int、char、pointer之类的基本数据类型被内置到语言中。用户定义的类型构建在基元类型的顶部。

    C++用户定义的一些类型是可以在引擎盖下执行一些用户定义操作的类。 std::string 就是这样的类型。使用构造函数初始化String类型的对象。

    C++中所有引用的字符串都是const字符集,这意味着程序没有修改它们的权限。

    const char *str = "abc"; 只声明指向常量字符串“abc”的指针。因此,它必须是“const”。

    std::string stdstr = "abc"; 声明类的对象 string 从命名空间 std . 对象的初始化调用 一串 . 后者将字符串复制到内部存储器中。copy不能修改“abc”字符集。所以,没有冲突。

    在第一种情况下,您不能修改指针,换句话说 str[1] = 'd'; 是非法的。直接修改常量(只读)字符串是很麻烦的。在第二种情况下,你 可以 修改 复制 “ABC”的。 stdstr[1] = 'd'; 是合法的。