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