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 ++标准的功能,而不必考虑旧系统。
答案 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';
是合法的。