在 C++ 中,这是用字符串文字初始化 char 数组的好习惯吗?

in c++ is this a good practice to initialize char array with string literal?

在 C++ 中,用字符串初始化 char 数组是一种好习惯吗? 如:

char* abc = (char *) ("abcabc");

我在我同事的代码中看到了很多这样的东西。我应该把它改成正确的做法吗? 比如

std::string abc_str = "abcabc";
const char* abc= abc_str .c_str();

此声明

char* abc = (char *) ("abcabc");

简直糟透了。 C++ 中的字符串文字具有常量字符数组类型。所以一个有效的声明看起来像

const char *abc = "abcabc";

注意:在 C 中你确实可以写

char *abc = "abcabc";

尽管如此,字符串文字是不可变的。任何修改字符串文字的尝试都会导致未定义的行为。

顺便说一下,没有任何由字符串文字初始化的字符数组。:)也许你的意思如下

char abc[] = "abcabc";

使用标准 class 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 的对象而不是指针是没有意义的。

因此声明的含义完全不同。

char* abc = (char *) ("abcabc");

这很糟糕。别这样。

您正在处理一个不应被修改的字符串文字,就像它可以被修改一样。

之后,

abc[0] = 'd';

编译器可以,但在 运行 时不可以。您需要使用的是:

char abc[] = "abcabc";

这将创建一个可修改的数组。

这两个都不好。

char* abc = (char*) ("abcabc");

字符串文字是常量,因此可以存储在写保护内存中。因此写入它可能会使您的程序崩溃,这是未定义的行为。

与其丢弃 constness,不如保留它 const 并制作一个 copy 如果你想编辑它内容。

const char* abc = "abcabc";

另一个也应该避免:

std::string abc_str = "abcabc";
const char* abc = abc_str.c_str();

保持常量很好,但如果更改字符串,它可能会重新分配到内存中的另一个位置,从而使您的指针悬空。

同样在 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