从字符串字面值初始化字符数组是否属于数组复制初始化的情况?
Would initialising a character array from a string literal be a case of array copy initialisation?
在我的脑海中,我一直认为用文字的类型和值的临时变量代替文字的任何使用是好的。如果这个是的情况下,因为字符串字面值的类型是const char数组将初始化一个字符数组通过字符串字面值不被认为是数组复制初始化?如不会
const char test1[] = "hello";
在某种程度上与做…相同
const char temp[6] = {'h', 'e', 'l', 'l', 'o', ' '};
const char test2[] = temp;
将被禁止,因为这是一个数组复制初始化的例子?如果字面值的类型是数组,那么如何使用字符串字面值来初始化数组?也许有些相关,如果字符串字面量是const char类型的数组,那么下面的代码如何在我的系统上编译得很好?
char* test3 = "hello";
由于test3缺少低级const,编译器错过了这种非法转换,但它编译得很好?当然,试图通过test3更改任何元素都会导致程序崩溃。
对于数组,复制和直接初始化没有区别。这两种情况都由编译器处理。你在开头所做的类比更多的是一个经验法则。实际上,一个数组不能被另一个数组初始化,除非它是字符串字面值。顺便说一句,你的类比并不完全正确。目标数组将使用临时数组直接初始化:
const char test2[](test1);
但是由于同样的原因,这仍然无法编译。这就是字符数组初始化的工作原理。
[dcl.init]/p17:
初始化式的语义如下:目标类型是被初始化的对象或引用的类型,源类型是初始化表达式的类型。如果初始化式不是单个(可能带圆括号)表达式,则未定义源类型。
- 如果初始化器是(未加括号的)带括号的init-list,对象或引用被列表初始化(8.5.4)。
- 如果目的类型是引用类型,请参见8.5.3。
- 如果目标类型是字符数组、
char16_t
数组、char32_t
数组或wchar_t
数组,且初始化项是字符串字面值,请参见8.5.2
8.5.2:
窄字符类型(3.9.1)的数组、
char16_t
数组、char32_t
数组、wchar_t
数组可以通过窄字符串字面值、char16_t
字符串字面值、char32_t
字符串字面值或宽字符串字面值进行初始化。分别,或用大括号括起来的适当类型的字符串字面值(2.13.5)。字符串字面值的连续字符初始化数组的元素。(例子:char msg[] = "Syntax error on line %sn";
显示了一个字符数组,其成员用字符串字面值初始化。[. .]
在您的另一个示例中,字符串字面值衰减为指向其第一个元素的指针,test3
就是用这个元素初始化的。这段代码在c++ 111中无效,因为衰减的指针是const char*
,但在C中这是一个有效的转换,因为字符串字面值是非const的。在c++ 03之前,它是被允许使用的,但后来被弃用了。
1:一些编译器仍然允许c++ 11中的转换作为扩展。
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在函数内部的声明中初始化数组,并在外部使用它
- 为什么用结构初始化数组需要指定结构名称
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++使用另一个数组和新值初始化数组
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 在 constexpr 构造函数中初始化数组是否合法?
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在构造函数中初始化数组
- 是否可以使用函数返回的值初始化数组
- 使用宏使用额外元素初始化数组
- 在循环中显示不同值的初始化数组
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 使用可变模板列表初始化数组,并放置new
- 使用函数从 Visual Studio 2017 中的 main 创建和初始化数组
- 使用 c++ 中的函数初始化数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- C++ 使用变量而不是常量表达式初始化数组
- 在初始化列表中初始化数组的更好方法
- 在可变参数模板类中初始化数组