C++ 从字符串文本初始化字符数组是否属于数组副本初始化?

C++ 从字符串文本初始化字符数组是否属于数组副本初始化?,c++,arrays,string,literals,C++,Arrays,String,Literals,在我看来,我一直认为用文字类型和值的临时变量替换文字的任何用法都是好的。如果是这种情况,由于字符串文字的类型为常量字符数组,那么通过字符串文字初始化字符数组是否不被视为数组副本初始化?例如,我不愿意 const char test1[] = "hello"; 有点像做 const char temp[6] = {'h', 'e', 'l', 'l', 'o', '\0'}; const char test2[] = temp; 这是阵列副本初始化的一个示例,因此禁止使用哪种方法?如果字符串的

在我看来,我一直认为用文字类型和值的临时变量替换文字的任何用法都是好的。如果是这种情况,由于字符串文字的类型为常量字符数组,那么通过字符串文字初始化字符数组是否不被视为数组副本初始化?例如,我不愿意

const char test1[] = "hello";
有点像做

const char temp[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
const char test2[] = temp;
这是阵列副本初始化的一个示例,因此禁止使用哪种方法?如果字符串的类型是数组,那么如何使用字符串来初始化数组?可能有点相关,如果字符串文字是const char的array类型,那么下面的代码在我的系统上编译得如何

char* test3 = "hello";

由于test3缺少低级常量,编译器会错过这种非法的转换,但它编译得很好?当然,试图通过test3更改任何元素都会导致程序崩溃

阵列的复制或直接初始化之间没有区别。编译器对这两种情况的处理是相同的。你在一开始所做的类比更多的是一种经验法则。实际上,一个数组不能由另一个数组初始化,除非它是字符串文本。顺便说一句,你的比喻并不完全正确。目标阵列将使用临时阵列直接初始化:

const char test2[](test1);
但出于同样的原因,这仍然无法编译。这就是字符数组初始化的工作方式

[dcl.init]/p17:

初始值设定项的语义如下所示。目标类型是要初始化的对象或引用的类型,源类型是初始化器表达式的类型。如果初始值设定项不是单个(可能带括号)表达式,则不定义源类型

  • 如果初始值设定项是一个(非圆括号)带括号的初始列表,则对象或引用将被列表初始化(8.5.4)
  • 如果目的地类型为参考类型,请参见8.5.3
  • 如果目标类型是字符数组、
    char16\u t
    数组、
    char32\u t
    数组或
    wchar\u t
    数组,且初始值设定项是字符串文字,请参见8.5.2。
8.5.2:

窄字符类型(3.9.1)、
char16\u t
array、
char32\u t
array或
wchar\u t
array的数组可以由窄字符串文字、
char16\u t
string文字、
char32\u t
string文字或宽字符串文字初始化, 或者使用大括号(2.13.5)中包含的适当类型的字符串文字。字符串文本值的连续字符初始化数组的元素。[示例:

显示其成员用字符串文字初始化的字符数组。[..]

在您的另一个示例中,字符串文字衰减为指向其第一个元素的指针,并使用该元素初始化
test3
。此代码在C++111中无效,因为衰减的指针是
const char*
,但这在C中是一个有效的转换,因为字符串文字是非常量的。直到C++03不推荐使用它时,才允许使用此代码。



1:有些编译器仍然允许C++11中的转换作为扩展。

是两个无法编译的东西“被认为是相同的”?@juanchopanza只有在错误相同的情况下,我想。:@juanchopanza好吧,我输入的第一行不正确。但是产生错误的第二个代码是我的问题的重点。我编辑了我的帖子,以便更清楚一点。请记住,字符串文字的类型是一个字符数组,所以
const char test1[]=“你好”
没有复印。
char msg[] = "Syntax error on line %s\n";