Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 常量字符[]和常量字符之间的差异*_C++_Arrays_Pointers_Constants_C Strings - Fatal编程技术网

C++ 常量字符[]和常量字符之间的差异*

C++ 常量字符[]和常量字符之间的差异*,c++,arrays,pointers,constants,c-strings,C++,Arrays,Pointers,Constants,C Strings,因此,在讨论如何使用const char*foo=foo这样的字符串文字时,以声明结尾: 常量char*foo=foo; 几乎从来都不是你想要的。相反,您希望使用以下表单之一: 对于要导出的字符串: const char foo[]=foo; 对于要在同一源文件中使用的字符串: 静态常量char foo[]=foo; 对于要跨同一库的多个源文件使用的字符串: __属性_uu可见性隐藏常量char foo[]=foo; 我在这里的理解是,const char*const foo=foo等同于con

因此,在讨论如何使用const char*foo=foo这样的字符串文字时,以声明结尾:

常量char*foo=foo; 几乎从来都不是你想要的。相反,您希望使用以下表单之一:

对于要导出的字符串: const char foo[]=foo; 对于要在同一源文件中使用的字符串: 静态常量char foo[]=foo; 对于要跨同一库的多个源文件使用的字符串: __属性_uu可见性隐藏常量char foo[]=foo; 我在这里的理解是,const char*const foo=foo等同于const char foo[]=foo,这仅仅是因为我们所说的C字符串指针永远不能更改为指向任何其他C字符串,而const char*foo=foo可以用于指向任何其他C字符串


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

让我们学究一点

char const * const p_foo = "foo";
上面定义了一个指向{constant}字符文本foo的{constant}指针。指针指向字符文本的单个第一个字符

const char bar[] = "bar";
上面定义了一个字符数组。 字符数组是*只读的。 字符数组是文本文字栏的长度加上 nul终止符4个字符。 文本文字的内容将复制到数组中。这个 编译器可能会优化这一步。 从根本上讲,指向文字的第一个字符的指针与数组之间存在差异

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

对于数组,如果数组长度为2或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++禁止将字符串常量转换为'char * '-WWORD字符串 char*a=foo

而您试图对字符串所做的任何更改通常都会导致分段错误。

因为声明const char*和const char*const都是指针,const char[]是数组

但是,使用指针有3个问题:

需要用于指针存储的内存 指针产生的间接寻址是必需的 指针需要单独存储数组的结束指针或数组大小 最终在链接中证明:

简单的答案是,在声明变量时,您应该更喜欢const char[]


数组是数组,指针是指针。虽然数组可以衰减为指针,但它们不是一回事。const char foo[]=foo不是指针。它是一个独立的数组。因此,在形式上,const char*const foo=foo并不等价。后者确实是一个指针。在这里发现了一些东西:一个小小的挑剔:文本是未命名的常量,所以const char*foo不是一个文本,只有foo是。const char*const将阻止您调用许多c字符串函数