常量字符 [] 和常量字符*之间的区别
Difference Between const char[] and const char*
所以这篇文章正在讨论声明字符串文字的使用,就像它以声明结尾const char* foo = "foo"
const char *foo = "foo";
几乎从来都不是你想要的。相反,您希望使用以下形式之一:
- 对于要导出的字符串:
const char foo[] = "foo";
- 对于要在同一源文件中使用的字符串:
static const char foo[] = "foo";
- 对于要跨同一库的多个源文件使用的字符串:
__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";
上面定义了一个指向 {常量} 字符文字"foo"的{常量}指针。指针指向字符文本的第一个字符。
const char bar[] = "bar";
- 上面定义了一个字符数组。
- 字符数组是*只读的"。
- 字符数组是文本文字"bar"的长度加上 NUL 终止符(4 个字符(。 文本
- 文本的内容将复制到数组中。(的 编译器可能会优化此步骤(。
从根本上说,指向文本第一个字符的指针和数组之间存在差异。
指针指向单个字符。递增指针可能不会指向有效的实体(因为它不是数组,而是指向单个基准面的指针(。 有一个基本假设,即指针可以递增到下一个字符。
对于数组,您知道内存中顺序有多个字符(前提是数组的长度为 2 或更大(。 您不知道序列(集合(中是否存在终止 NUL。 您可以假设这一点,但字符数组并不能保证这一点。
用法
使用数组声明,文本的长度在编译时是已知的。
使用指针声明时,需要使用strlen
来确定运行时文本的长度。 运行时代码不知道目标数据字符串的长度;只能保证长度为 1。
有时,使用static
和const
可以帮助编译器进行优化。
例如:
static const char moo[] = "moo";
允许编译器直接访问文本,而无需创建数组变量并将文本复制到变量中。
在接收指向字符的指针的函数中,无法保证指针指向有效位置(指针的内容可能无效(。
每个声明都有其优点和副作用。
选择权在你。
正如托马斯·马修斯的回答所说,const char*
和const char* const
都是指针,const char[]
是数组。
但正如这里所说的那样,使用指针有 3 个问题:
- 需要用于指针存储的内存
- 指针产生的间接寻址是必需的 指针
- 需要单独存储数组或数组大小的结束指针
最终如链接中所示:
简单的答案是,在声明变量时,您应该首选
const char[]
。
我同意数组在计算时会衰减为指针,但有一些功能仅适用于数组。例如,当您声明一个数组时,您有关于数组大小的其他信息。
此外,对于固定数组的情况,内存是专门为 foo 分配的。因此,您可以像往常一样更改数组的内容,并且数组将被销毁,在超出范围(典型的局部变量(时解除分配内存。
当您将其定义为指针时,编译器会将 foo 放入只读内存中,然后指向它(通常(。请注意,这就是为什么大多数情况下常量字符串被定义为 char*,甚至编译器也会在将其设置为非常量指针时发出警告。
#include <iostream>
int main()
{
char* a = "foo";
return 0;
}
此代码会向您抛出如下警告:
ISO C++禁止将字符串常量转换为"char*" [-Wwrite-strings] 字符* a = "foo";
您尝试对字符串进行的任何更改通常都会导致分段错误。
- 如何循环访问常量字符**?
- constexpr 函数获取常量字符*
- 如何计算常量字符**中的总字符数?
- QDial:如何将 int 值传递给需要常量字符*的 Qfile?
- 为什么 std::string_view 比常量字符*快?
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 在编译时将常量字符* 转换为常量 char_type*
- 将字符串数组传递给接受常量字符**的函数
- 错误:请求从"常量字符 [5]"转换为非标量类型"字符串"
- 字符串强制转换为常量字符*
- 使用常量字符*时退出代码 139
- 为什么我可以隐式地将字符*转换为常量字符*,但不能将无符号字符*
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- 无法<string>从"常量字符 []"转换为<类名>
- 初始化常量字符* 数组
- 常量字符*的性质是什么?
- C++ 获取向量中常量字符* [ ] 的长度
- 无法将参数 1 从 WCHAR 转换为常量字符 *
- 如何在 c++ 中将向量转换为<string>常量字符* const*?
- C++将常量字符* 指针数组传递给对象