【问题标题】:C++ structure initialization with all zeros全零的 C++ 结构初始化
【发布时间】:2016-10-09 01:45:54
【问题描述】:

在 C++ 中,如果我以“= {}”的形式初始化结构,如下例所示,它是否确保为结构的所有成员分配零值? 我理解这个看似重复的问题,但我的问题也是,如果它对所有成员初始化为零,它是否也适用于复杂结构? 像结构中的结构,或者为此必须在代码中为每个成员显式分配零值?


typedef struct s{
      int i;
      bool x;
 };

  int main ()
 {
     s initial = {};
     printf("%d %d", initial.i, initial.x);

 }

编辑:引用复杂结构,

typedef struct scomplex{
    s initial;
    s t[5];
 };
  int main (void)
  {
     scomplex sc = {};
     printf ("%d %d %d",sc.initial.i, sc.initial.x, sc.t[0].i);  
  }

【问题讨论】:

  • en.cppreference.com/w/cpp/language/value_initialization 这是值初始化,因为没有用户定义的默认构造函数。
  • 如果您不希望将其作为重复项关闭,请发布一些不重复的示例代码。
  • @lapk 这是聚合初始化,不是值初始化
  • @M.M 我认为,它是struct s聚合初始化,但struct s 的非类类型成员的值初始化(因为struct s) 没有默认的用户定义构造函数,因此它们被0 初始化。我错了吗?
  • 当然,所有值都将为零。请参阅(聚合初始化)en.cppreference.com/w/cpp/language/aggregate_initialization

标签: c++ struct initialization


【解决方案1】:

但我的问题也是,如果它对所有成员初始化为零,它是否也适用于复杂结构?

是的,所有成员都会被初始化,包括“复杂”成员,但可能不会初始化为零,最终效果取决于它们的类型。

根据您的示例代码,struct s 是一个聚合类型,然后执行aggregate initialization

(强调我的)

如果初始化子句的数量小于成员and bases (since C++17)初始化列表完全为空,则剩余成员and bases (since C++17)由空列表初始化by their default initializers, if provided in the class definition, and otherwise (since C++14),按照使用通常的list-initialization 规则(使用默认构造函数对非类类型和非聚合类执行值初始化,并为聚合执行聚合初始化)。

对于这种情况,结构s 的成员ixvalue initialized 为零。

4) 否则,对象被零初始化。

如果 struct s 有任何其他成员,它们将被空列表递归地初始化(根据其类型初始化值或聚合初始化)。

编辑

对于您添加的样本(结构scomplex),成员initial 将为value initialized,最终效果取决于类型s。另一个成员是一个数组,它将是aggregate initialized,带有空列表,并且数组的所有元素都将被初始化;与成员initial相同,效果取决于s的类型。

【讨论】:

  • 阅读和引用 C++ 标准远非微不足道:“如果初始化子句的数量少于成员的数量”会使您的答案不完整。
  • @DieterLücking 抱歉,我不明白你的意思,哪一部分不完整? “如果初始化子句的数量小于成员的数量”不是问题的重点,它只是被引用(为了完整性)。
【解决方案2】:

问题

这会将所有成员初始化为 0 吗?

typedef struct s{
      int i;
      bool x;
 };

int main ()
{
     s initial = {};
     printf("%d %d", initial.i, initial.x);

}

回答:是的。证明? Here你可以看到它变成了0。

更好的选择?

这是一个自以为是的部分。但在我的意见 (IMO) 中,使用 {0} 对其进行初始化会比 {} 更具可读性,因为它会将 0 通知给用户。它实际上是用 0 填充的。

s initial = {0};

这叫什么?

这被称为Aggregate Initialization,如Dieter Lücking 所定义,或Value Initialization,如songyuanyao 所述。它基本上是一种初始化形式,您可以在其中使用您想要的值初始化结构。例如,让我们用值 1 而不是 0 来初始化它!你会这样做:

// Example program
#include <stdio.h>
#include <iostream>


typedef struct s{
 int i;
 bool x;
};
    
int main ()
{
   s initial = {1,1};
   printf("%d %d", initial.i, initial.x);
}

您可以在此处查看此编译结果。正如你在上面看到的,我正在做1,1,这是正常的初始化。与 0 初始化相反,您不能像使用 0 那样简单地初始化结构的所有部分。

参考文献

cpprefrence

what is aggregate initialization

What do the following phrases mean in C++: zero-, default- and value-initialization?

词汇表

聚合初始化

聚合初始化是列表初始化的一种形式,它对聚合进行初始化。

值初始化

初始化值

这是使用空初始化器构造变量时执行的初始化。

【讨论】:

  • 为什么给其中一个成员赋值更易读。根据您的逻辑,{1} 会通知用户它正在被 1 填满。
  • @M.M 对不起,我的意思是1,1 .. 当您输入您知道的答案时,确实会发生意外;)
  • @M.M 好的,我完成了编辑问题。如果你有批评者,很乐意听到:)
  • 遵循公式的格式良好的答案。长文,少说。
  • 我知道这是两年后的事了,但我认为应该说:编译程序不是证明,即使它很好地表明了预期的行为。 (只是因为很多 c++ 行为可以实现定义或根本不定义)
猜你喜欢
  • 2023-03-11
  • 2011-02-01
  • 1970-01-01
  • 2015-07-30
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多