【问题标题】:in c++ is this a good practice to initialize char array with string literal?在 C++ 中,这是用字符串文字初始化 char 数组的好习惯吗?
【发布时间】:2015-05-12 17:47:26
【问题描述】:

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

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

我在同事的代码中看到了很多这样的内容。我应该将其更改为正确的做法吗? 比如

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

【问题讨论】:

  • 我没有看到 char 数组。
  • @BufBills 好吧,这对我来说是个新闻。
  • 我向你保证@T.C.比你知识渊博。
  • 您的第一个示例很糟糕,因为您正在从字符串文字中丢弃常量。你的第二个例子很糟糕,因为如果 abc_str 被修改,abc 可能指向无效内存。
  • 旁注:请不要转换 const 字符串字面量使用:const char* s = hello"(非 const 已弃用)

标签: c++ string declaration c-strings string-literals


【解决方案1】:

此声明

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 类型的对象而不是指针是没有意义的。

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

【讨论】:

    【解决方案2】:
    char* abc = (char *) ("abcabc");
    

    这很糟糕。不要这样做。

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

    之后,

    abc[0] = 'd';
    

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

    char abc[] = "abcabc";
    

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

    【讨论】:

      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-31
        • 1970-01-01
        • 1970-01-01
        • 2012-03-10
        相关资源
        最近更新 更多