所以this article正在讨论声明像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-String。
这是一个准确的概要吗?始终使用const char* const
或const char[]
?
答案 0 :(得分:2)
让我们在这里变得迂腐。
char const * const p_foo = "foo";
上面定义了 {constant} 指向 {constant} 字符文字" foo"的指针。指针指向字符文字的单个第一个字符。
const char bar[] = "bar";
从根本上说,指向文字的第一个字符和数组的指针之间存在差异。
指针指向单个字符。增加指针可能不指向有效实体(因为它不是数组,而是指向单个数据的指针)。有一个基础假设指针可以递增到下一个字符。
使用数组,您知道内存中有多个字符(如果数组长度为2或更长)。你不知道序列(集合)中是否有终止nul。你可以假设,但是一组字符并不能保证这一点。
<强>用法强>
使用数组声明,文本的长度在编译时是已知的。
使用指针声明,您需要使用strlen
来确定运行时文本的长度。运行时代码不知道目标数据字符串的长度;只能保证长度为1。
有时,使用static
和const
可以帮助编译器进行优化
例如:
static const char moo[] = "moo";
允许编译器直接访问文本而无需创建数组变量并将文本复制到变量中。
在接收指向字符的指针的函数中,您不能保证指针指向有效位置(指针的内容可能无效)。
每份声明都有其好处和副作用 选择权在你手中。
答案 1 :(得分:2)
由于Thomas Matthews' answer指出const char*
和const char* const
都是指针,而const char[]
是数组。
但是here是合理的,使用指针存在3个问题:
最终在链接中证明是正确的:
简单的答案是,在声明变量时,您应该首选
const char[]
。
答案 2 :(得分:0)
我确实同意数组在被评估时衰减成指针,但有一些功能只有数组。例如,当您声明一个数组时,您可以获得有关数组大小的其他信息。
此外,对于固定数组的情况,内存专门为foo分配。因此,您可以像往常一样更改数组的内容并销毁数组,在超出范围(典型的局部变量)时释放内存。
当您将其定义为指针时,编译器将foo置于只读内存中,然后指向它(通常)。请注意,这就是大多数情况下常量字符串被定义为char *的原因,甚至编译器会在您将其设置为非常量指针时发出警告。
#include <iostream>
int main()
{
char* a = "foo";
return 0;
}
此代码会向您发出如下警告:
ISO C ++禁止将字符串常量转换为'char *'[ - WRrite-strings] char * a =&#34; foo&#34 ;;
并且您尝试对字符串进行的任何更改通常会导致分段错误。