const char[] 和 const char* 的区别

Difference Between const char[] and const char*

所以 this article 正在讨论声明字符串文字的使用 const char* foo = "foo" 它以声明结尾:

const char *foo = "foo";
is almost never what you want. Instead, you want to use one of the following forms:

  • For a string meant to be exported:
    const char foo[] = "foo";
  • For a string meant to be used in the same source file:
    static const char foo[] = "foo";
  • For a string meant to be used across several source files for the same library:
    __attribute__((visibility("hidden"))) const char foo[] = "foo";

我的理解是 const char* const foo = "foo" 等同于 const char foo[] = "foo" 只是因为我们谈论的是一个永远不能更改为指向其他任何东西的 C 字符串指针,而 const char* foo = "foo" 可用于指向任何其他 C 字符串。

这是一个准确的概要吗?始终使用 const char* constconst char[]?

让我们在这里迂腐。

char const * const p_foo = "foo";

上面定义了一个{constant}指向{constant}字符文字"foo"的指针。指针指向字符文字的 单个 第一个字符。

const char bar[] = "bar";
  • 上面定义了一个字符数组
  • 字符数组是*只读的。
  • 字符数组是文本文字的长度"bar"加上一个 nul 终止符(4 个字符)。
  • 文本文字的内容被复制到数组中。 (这 编译器可能会优化这一步。

从根本上说,指向文字第一个字符的指针和数组是有区别的。

指针指向一个单个字符。递增指针可能不会指向有效实体(因为它不是数组,而是指向单个数据的指针)。有一个 基本假设 指针可以递增到下一个字符。

使用数组,您知道内存中有多个连续字符(前提是数组的长度为 2 或更大)。您不知道序列(集合)中是否有终止 nul。您可以假设,但字符数组并不能保证这一点。

用法
通过数组声明,文本的长度在编译时已知。

使用指针声明,您需要使用 strlen 来确定 运行 时的文本长度。 运行-时间码不知道目标数据串的长度;只能保证1的长度。

有时,使用staticconst可以帮助编译器优化。
例如:

static const char moo[] = "moo";

允许编译器直接访问文本,而无需创建数组变量并将文本复制到变量中。

在接收字符指针的函数中,不能保证指针指向有效位置(指针的内容可能无效)。

每种声明都有其优点和副作用。
选择权在你。

我同意数组在求值时会衰减为指针,但有一些功能只有数组才有。例如,当你声明一个数组时,你有关于数组大小的额外信息。

此外,对于固定数组的情况,内存是专门为 foo 分配的。所以你可以像往常一样更改数组的内容并且数组被销毁,当它超出范围时释放内存(典型的局部变量)。

当您将它定义为指针时,编译器会将 foo 放入只读内存,然后指向它(通常)。请注意,这就是为什么大多数情况下常量字符串被定义为 char* 并且当您将其设置为非常量指针时甚至编译器也会警告您的原因。

#include <iostream>
int main()
{
    char* a = "foo";
    return 0;
} 

此代码会向您发出如下警告:

ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] char* a = "foo";

您尝试对字符串进行的任何更改通常会导致分段错误。

As 表示 const char*const char* const 都是指针,而 const char[] 是数组。

但是有理由here使用指针有3个问题:

  1. 需要用于指针存储的内存
  2. 需要指针引起的间接寻址
  3. 指针需要单独存储数组的结束指针或数组大小

最终在 link 中证明:

The simple answer is that when declaring a variable you should prefer a const char[].