何时使用const char *以及何时使用const char

我知道他们是不同的,我知道他们是如何不同,我读了所有问题,我可以find关于char* vs char[]

但是,所有这些答案永远不会告诉他们何时应该使用。

所以我的问题是:

你什么时候用

 const char *text = "text"; 

你什么时候用

 const char text[] = "text"; 

有没有任何指导原则或规则?

举个例子,哪一个更好:

 void withPointer() { const char *sz = "hello"; std::cout << sz << std::endl; } void withArray() { const char sz[] = "hello"; std::cout << sz << std::endl; } 

(我知道std::string也是一个选项,但我特别想知道关于char指针/数组)

两者截然不同,首先:

  1. 第一个创build一个指针。
  2. 第二个创build一个数组。

阅读更详细的解释:

arrays版本:

 char text[] = "text"; 

创build一个足够大的数组来保存string文本“text”,包括NULL终止符。 数组text是用string文字“text”初始化的。 该数组可以稍后修改 。 此外,数组的大小即使在编译时也是已知的,所以sizeof运算符可以用来确定它的大小。


指针版本:

 char *text = "text"; 

创build一个指向string文字“text”的指针。 这比数组版本快, 但指针指向的string不应该改变 ,因为它位于只读实现定义的内存中。 修改这样的string会导致未定义的行为

事实上,C ++ 03不赞成使用不带const关键字的string。 所以声明应该是:

 const char*text = "text"; 

另外,你需要使用strlen()函数,而不是sizeof来查找string的大小,因为sizeof运算符只会给你指针variables的大小。


哪个版本更好?

取决于使用情况。

  • 如果不需要对string进行任何更改,请使用指针版本。
  • 如果您打算更改数据,请使用arrays版本。

编辑:它刚刚被带到我注意到(在评论中)OP寻求区别:

const char text[]const char* text

那么以上的不同点仍然适用,除了修改string文字。 使用const限定符,数组test现在是一个包含const chartypes元素的数组,这意味着它们不能被修改。

鉴于此,我会select指针版本的数组版本,因为指针可以(错误地)重新设置为另一个指针,并且可以通过另一个指针来修改string,从而产生UB。

也许最大的区别是你不能使用sizeof运算符的指针来获取开始指向的缓冲区的大小,在const char[]版本中,你可以使用sizeof对数组variables来获得内存占用的大小数组的字节数。 所以这真的取决于你想要做什么 – 用指针或缓冲区,以及如何使用它。

例如,做:

 void withPointer() { const char *sz = "hello"; std::cout << sizeof(sz) << std::endl; } void withArray() { const char sz[] = "hello"; std::cout << sizeof(sz) << std::endl; } 

会给你非常不同的答案。

一般来说,要回答这些types的问题,请使用最明确的问题

在这种情况下, const char[]获胜是因为它包含更多关于数据的详细信息,即缓冲区的大小。

只是一个说明:

我会使它static const char sz[] = "hello"; 。 声明这样做有一个很好的优势,就是通过写入只读内存来更改该常量string,从而使程序崩溃。 如果没有static ,抛弃常量然后改变内容可能会被忽视。

此外, static使数组简单地位于常量数据部分,而不是在堆栈上创build,并每次调用该函数时从常量数据部分复制。

如果使用数组,则数据在运行时被初始化。 如果使用指针,运行时开销可能会减less,因为只有指针需要被初始化。 (如果数据小于指针的大小,那么数据的运行时初始化小于指针的初始化。)因此,如果您有足够的数据,那么您关心运行时初始化的成本,你应该使用一个指针。 你几乎不应该关心这些细节。

几年前,Ulrich Drepper的博客文章给了我很多帮助:

如此接近,但没有雪茄和更多的arrays乐趣

博客的要点是, const char[]应该是首选,但只能作为全局或静态variables。

使用指针const char*有一个缺点:

  1. 一个额外的variables
  2. 指针是可写的
  3. 一个额外的间接
  4. 通过指针访问string需要2个内存加载