这是一个用字符串初始化char数组的好习惯吗? 如:
char* abc = (char *) ("abcabc");
我在同事的代码中看到了很多这些。我应该改变它吗? 比如
std::string abc_str = "abcabc";
const char* abc= abc_str .c_str();
答案 0 :(得分:12)
本声明
char* abc = (char *) ("abcabc");
简直太糟糕了。 C ++中的字符串文字具有常量字符数组的类型。所以有效的声明看起来像
const char *abc = "abcabc";
注意:在C中你确实可以写
char *abc = "abcabc";
然而,字符串文字是不可变的。任何修改字符串文字的尝试都会导致未定义的行为。
顺便说一句,没有任何由字符串文字初始化的字符数组。:)也许你的意思是以下
char abc[] = "abcabc";
使用标准类std::string
不排除使用字符数组以及指向字符串文字的指针。
考虑到这些声明
const char *abc = "abcabc";
和
std::string abc_str = "abcabc";
const char* abc= abc_str .c_str();
不等同。相对于第一个声明字符串文字具有静态存储持续时间,并且在程序执行期间它们的地址不会更改。
在第二个声明中,指针abc
指向动态分配的内存,如果对象abc_str
将被更改,则可以重新分配该内存。在这种情况下,指针将无效。
此外,第一个声明假设指针指向的数组(字符串文字)不会被更改。在第二个声明中,假设将更改std :: string类型的对象。否则,声明一个std :: string类型的对象而不是指针是没有意义的。
因此,声明的含义完全不同。
答案 1 :(得分:5)
char* abc = (char *) ("abcabc");
这很糟糕。不要这样做。
您正在处理一个不应修改的字符串文字,因为它可以被修改。
之后,
abc[0] = 'd';
编译器可以正常,但在运行时不正常。你需要使用的是:
char abc[] = "abcabc";
这将创建一个可修改的数组。
答案 2 :(得分:3)
这两个都不好。
char* abc = (char*) ("abcabc");
字符串文字是常量,因此可以存储在写保护的内存中。因此,写入它可能会使程序崩溃,这是未定义的行为。
如果你想编辑它的内容,你应该保留它const
并制作副本,而不是丢弃 constness 。
const char* abc = "abcabc";
另一个也应该避免:
std::string abc_str = "abcabc";
const char* abc = abc_str.c_str();
保持const是好的但是如果字符串被更改,它可以被重新分配到内存中的另一个地方,让你的指针悬空。
同样在前C++11
代码中,指针在指定的第二个指针时停止有效,因为无法保证指针不是临时指针。
最好每次都致电abc_str.c_str()
。
可能因为c_str()
是如此微不足道的操作,它将被编译器优化掉,使其与使用原始指针一样高效。
而不是应该正在做的那些事情,而不是一直使用std::string
。如果您完全需要 const char*
(对于旧的遗留代码),您可以使用c_str()
获取它。
std::string abc_str = "abcabc"; // this is perfect why do more?
old_horrible_function(abc_str.c_str()); // only when needed