我刚看到这个数组声明:
const int nNums= 4;
int* nums[nNums] = {0, 0, 0}, d[nNums];
我知道正在创建指向nums
的指针,但右边的业务是什么? d[]
已初始化,但我不确定{0,0,0}
的作用。
答案 0 :(得分:5)
int* nums[nNums] = {0, 0, 0}
定义了一个由4个整数指针组成的数组,每个指针都初始化为NULL。但请注意,d
是一个整数和不是整数指针的数组,并且这些值未初始化。
答案 1 :(得分:3)
该代码相当于:
const int nNums= 4;
int* nums[nNums] = {0, 0, 0};
int d[nNums];
因此,nums
是长度为4的int*
数组,所有四个元素都初始化为null; d
是一个长度为4的int
数组,所有四个元素未初始化(重新强调,d
不获取以任何方式初始化。)
此上下文中的语法= {0, 0, 0}
称为“聚合初始化”,并在C ++ 03标准的第8.5.1节中描述;该代码的相关部分(§8.5.1/ 2)规定:
初始化聚合时,初始值设定项可以包含 initializer-clause ,其中包含括号括起的,以逗号分隔的 initializer-clauses列表用于聚合的成员,以增加的下标或成员顺序编写。如果聚合包含子聚合,则此规则以递归方式应用于子聚合的成员。
因此,nums
的前三个元素显式初始化为0
,第四个元素隐式“值初始化”,如§8.5.1/ 7中所述:
如果列表中的初始值设定项少于聚合中的成员,则未显式初始化的每个成员都应进行值初始化。
值初始化在§8.5/ 5中描述:
value-initialize
T
类型的对象意味着:
- 如果
T
是具有用户声明的构造函数的类类型,则调用T
的默认构造函数(如果T
没有可访问的默认值,则初始化不正确构造函数);- 如果
T
是没有用户声明的构造函数的非联合类类型,那么T
的每个非静态数据成员和基类组件都是值初始化的;- 如果
T
是数组类型,则每个元素都是值初始化的;- 否则,该对象为零初始化
零初始化
T
类型的对象意味着:
- 如果
T
是标量类型,则将对象设置为0
(零)转换为T
的值;- 如果
T
是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;- 如果
T
是联合类型,则对象的第一个命名数据成员)是零初始化的;- 如果
T
是数组类型,则每个元素都是零初始化的;- 如果
T
是引用类型,则不执行初始化。
这导致nums
的第四个元素也被初始化为null。
答案 2 :(得分:1)
int* nums[nNums] = {0, 0, 0}, d[nNums];
因为@Asha已经说nums
是一个由4个整数指针组成的数组,每个指针都初始化为NULL。
这里可以进一步提出的有趣问题是:变量d
的类型是什么?
它是一个包含4个整数指针的数组吗?
或者
是4个整数的数组吗?
所以答案是:它是一个包含4个整数的数组。 *
仅与第一个声明的符号nums
相关联。
等效声明是这样的:
int* nums[nNums] = {0, 0, 0};
int d[nNums]; //not int* d[nNums];
为了避免这种混淆,我更喜欢在多行上写这样的声明。如果你想在一行中声明,第二个声明会更好一点:
int* nums[nNums] = {0, 0, 0}, d[nNums]; //old one!
int *nums[nNums] = {0, 0, 0}, d[nNums]; //new one. note the position of *
答案 3 :(得分:0)
>我明白指向nums的指针是 被创造,
你理解不正确。在该声明中没有创建“指向nums
的指针”。声明
int* nums[4] = {0, 0, 0};
声明一个包含4个指针的数组。 nums
本身就是一个数组,而不是指向任何东西的指针。
>但右边的业务是什么?
= {0, 0, 0}
部分称为“聚合初始值设定项”。它初始化nums
数组的第一个树元素。目前尚不清楚为什么只有三个显式初始化(而第四个被初始化为零隐式)。此外,在C ++中,可以通过
int* nums[4] = {};
声明,其中所有四个元素都被初始化为零隐式。
> d []初始化
咦?不。d
的声明等同于
int d[4];
意味着d
根本没有初始化。