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* const
或 const char[]
?
让我们在这里迂腐。
char const * const p_foo = "foo";
上面定义了一个{constant}指向{constant}字符文字"foo"的指针。指针指向字符文字的 单个 第一个字符。
const char bar[] = "bar";
- 上面定义了一个字符数组
- 字符数组是*只读的。
- 字符数组是文本文字的长度"bar"加上一个
nul 终止符(4 个字符)。
- 文本文字的内容被复制到数组中。 (这
编译器可能会优化这一步。
从根本上说,指向文字第一个字符的指针和数组是有区别的。
指针指向一个单个字符。递增指针可能不会指向有效实体(因为它不是数组,而是指向单个数据的指针)。有一个 基本假设 指针可以递增到下一个字符。
使用数组,您知道内存中有多个连续字符(前提是数组的长度为 2 或更大)。您不知道序列(集合)中是否有终止 nul。您可以假设,但字符数组并不能保证这一点。
用法
通过数组声明,文本的长度在编译时已知。
使用指针声明,您需要使用 strlen
来确定 运行 时的文本长度。 运行-时间码不知道目标数据串的长度;只能保证1的长度。
有时,使用static
和const
可以帮助编译器优化。
例如:
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个问题:
- 需要用于指针存储的内存
- 需要指针引起的间接寻址
- 指针需要单独存储数组的结束指针或数组大小
最终在 link 中证明:
The simple answer is that when declaring a variable you should prefer a 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* const
或 const char[]
?
让我们在这里迂腐。
char const * const p_foo = "foo";
上面定义了一个{constant}指向{constant}字符文字"foo"的指针。指针指向字符文字的 单个 第一个字符。
const char bar[] = "bar";
- 上面定义了一个字符数组
- 字符数组是*只读的。
- 字符数组是文本文字的长度"bar"加上一个 nul 终止符(4 个字符)。
- 文本文字的内容被复制到数组中。 (这 编译器可能会优化这一步。
从根本上说,指向文字第一个字符的指针和数组是有区别的。
指针指向一个单个字符。递增指针可能不会指向有效实体(因为它不是数组,而是指向单个数据的指针)。有一个 基本假设 指针可以递增到下一个字符。
使用数组,您知道内存中有多个连续字符(前提是数组的长度为 2 或更大)。您不知道序列(集合)中是否有终止 nul。您可以假设,但字符数组并不能保证这一点。
用法
通过数组声明,文本的长度在编译时已知。
使用指针声明,您需要使用 strlen
来确定 运行 时的文本长度。 运行-时间码不知道目标数据串的长度;只能保证1的长度。
有时,使用static
和const
可以帮助编译器优化。
例如:
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个问题:
- 需要用于指针存储的内存
- 需要指针引起的间接寻址
- 指针需要单独存储数组的结束指针或数组大小
最终在 link 中证明:
The simple answer is that when declaring a variable you should prefer a
const char[]
.