c++ c风格零初始化0

Posted

技术标签:

【中文标题】c++ c风格零初始化0【英文标题】:c++ c-style zero-initialization 0 c++ c风格零初始化0 【发布时间】:2020-01-25 20:53:37 【问题描述】:

https://en.cppreference.com/w/cpp/language/zero_initialization 表明零初始化发生在以下场景:

int array[32] = ;

;但从来没有说过这件事:

int array[32] =  0 ;

后者是否也在 c++ 中对整个数组进行零初始化,还是仅对第一个元素进行零初始化?如果是这样,结构体也是这样吗?

【问题讨论】:

后者使用起来特别特别,因为任何其他值都只初始化第一个元素(并将其余元素归零,感谢@ChrisDodd 澄清这一点)...... 对于它的价值,int array[4] = 1 ; 会产生 1, 0, 0, 0,所以不要认为后一种语法会使用该值初始化整个数组。 @Resurrection: not true -- 任何小于数组的数组初始化器都会将所有尾随(未指定)元素初始化为零。 类似的 C 语句:int array[32] = ; 导致编译器输出以下内容:“untitled2.c:1:17: warning: ISO C forbids empty initializer brackets [-Wpedantic]” 建议:@987654327 @ 注意大括号内的初始化程序。但是,如果要使用 0 以外的值,建议:for( size_t i = 0; i< 32; i++ ) array[i] = 1; C 语言和 C++ 语言有很大的不同,(并且随着每个新版本的发布越来越远)请选择一个并擦除另一个标签 【参考方案1】:

ISO/IEC N489 §9.4.1 状态

(5) 对于非联合聚合,每个不是显式初始化元素的元素都被初始化如下:

(5.1) 如果元素具有默认成员初始化程序 (11.4),则从该初始化程序初始化元素。

(5.2) 否则,如果元素不是引用,则从空的初始化列表 (9.4.4) 复制初始化元素。

(5.3) 否则,程序格式错误。

§9.4.4 状态

(3.11) 否则,如果初始化列表没有元素,则对象被值初始化。
标量的

值初始化导致其零初始化。因此,第二个元素显式初始化为 0,仅 array[0],其余元素将被初始化为零。


因此,下面的代码

int array[4] = 13;

用值初始化array

13, 0, 0, 0

【讨论】:

【参考方案2】:

后者是否也在 c++ 中对整个数组进行零初始化,还是仅对第一个元素进行零初始化?

是的。

第一种风格是C++风格。

第二个是老C风格。

两个零都初始化整个数组元素(不仅仅是第一个元素)。

如果是这样,结构体也是这样吗?

是的。

【讨论】:

两个零都初始化整个数组元素这可能会产生误导。仅当初始化程序中使用的值为0 时才为真。否则,任何小于数组大小的数组初始化器都会使用0 初始化尾随值。 是的,这就是0 的问题所在。你说的是正确的(如果初始化中使用的值是别的),谢谢 "第二个是旧的 C 风格" -- 有没有新的 C 风格呢?【参考方案3】:

...但从来没有说过这件事

确实如此。这实际上是aggregate initialization。

根据 cppreference:

如果初始化子句的数量小于成员和基的数量或初始化列表完全为空,其余成员和基将由其默认成员初始化器初始化,如果在类中提供定义,否则由空列表,按照通常的列表初始化规则(它对非类类型和具有默认构造函数的非聚合类执行值初始化,并为聚合执行聚合初始化) .如果引用类型的成员是这些剩余成员之一,则程序是非良构的。

这保证了数组的剩余元素用空列表初始化。对于int(标量),这会将其初始化为零。对于结构,如果结构不是聚合或聚合初始化,则这将执行值初始化。

【讨论】:

【参考方案4】:

使用CppInsights 看看实际发生了什么:

这个:

int main()

    int array0[5];
    int array1[5] = ;
    int array2[5] =  0 ;
    int array3[5] =  -1 ;
    int array4[5] =  1, 2 ;

相当于:

int main()

  int array0[5];
  int array1[5] = 0, 0, 0, 0, 0;
  int array2[5] = 0, 0, 0, 0, 0;
  int array3[5] = -1, 0, 0, 0, 0;
  int array4[5] = 1, 2, 0, 0, 0;

所以,int array2[5] = v v 显式初始化第一个元素,并默认初始化所有其他元素。

【讨论】:

以上是关于c++ c风格零初始化0的主要内容,如果未能解决你的问题,请参考以下文章

C++ 字符串

如何在 C 或 C++ 中全局初始化数组?

C++中,类内的成员变量自动初始化为零吗,而全局变量随意赋值

初始化 c 风格的结构

C++ --- 字符串与字符数组

C ++:如何用非零大小初始化地图中的向量