为什么初始化char * []时需要const而string []不需要?

时间:2019-04-22 01:34:18

标签: c++

char* c_arguments[] = { "hi","bye" }; //(1)
std::string cpp_arguments[]= { "hi","bye" };

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

  

E0144:类型“ const char *”的值不能用于初始化   类型为“ char *”的实体

如果我在开头添加const,则代码可以正常编译。

但是为什么第一行需要const但第二行不需要const

如何从字符串文字数组中创建不带const的char*[]

该代码可以使用最新C ++标准的功能,而不必考虑旧系统。

4 个答案:

答案 0 :(得分:2)

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

要创建指向可写字符串的指针数组,必须像std::string构造函数那样遍历并创建每个文字的副本。

答案 1 :(得分:2)

字符串是对象,在后台,编译器将创建两个const char*缓冲区,然后将这些值复制到字符串对象中以提供可变数组。如果需要,您可以执行相同的操作来创建char*指针。

我不建议在C ++中使用不带常量的文字char*指针。有很多方法可以弄乱它们。如果要修改字符缓冲区,应将它们包装在字符串中并使用适当的库函数。

答案 2 :(得分:2)

第一种类型c_是指向char的指针的数组。第二种类型cpp_std::string s的数组。

"string"传递给指针时,它将生成指向第一个元素的指针。但是"hello"中的数据类型为const;因此char*不想指向它。相反,您需要一个char const*或一个指向const char的指针。

对于std::string,当您将"hello"传递给它时,它会将字符复制std::string所拥有的缓冲区中。该副本可以是可变的,因此不需要const

有些编译器标志在将const字符串文字分配给"hello"时放弃了对char*的需要;但是,它们的存在是为了与const之前编写的代码兼容。避免使用它们。如果您在使用这些标志后意外地修改了字符串常量,则可能会出现不确定的行为(很可能在字符串池中造成精神错乱)

答案 3 :(得分:1)

在c ++中,基本上有原始数据类型和用户定义的数据类型。语言中内置了int,char,pointers等原始数据类型。用户定义的类型建立在基本类型的顶部。

某些C ++用户定义类型是可以在后台执行某些用户定义操作的类。 std::string就是这种类型。使用构造函数初始化字符串类型的对象。

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

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

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

在第一种情况下,您无法修改指针,换句话说str[1] = 'd';是非法的。它会直接修改常量(只读)字符串。在第二种情况下,您可以修改“ abc”的副本stdstr[1] = 'd';是合法的。