【问题标题】:Difference between two struct initializations两个结构初始化之间的区别
【发布时间】:2021-04-12 16:33:36
【问题描述】:

Struct 的以下两个初始化有什么区别?

Car ford = {
    .name = "Ford F-150",
    .price = 25000
};

还有:

Car dodge = (Car) {
    .name = "Ram",
    .price = 1000
};

来自Compiler Explorer,看起来两者产生了相同的代码:


(StructName) 在结构体之前有什么作用?在进行复杂的初始化时似乎是必要的,例如:

CarPtr mazda = & (Car) {
    .name = "Mazda",
    .price = 20000
};

也与Possible to initialize/assign a struct pointer? 的两个答案有关。

【问题讨论】:

  • 查看这个关于compound literals 的问答。也许不是最好的帖子,但还有很多其他关于 C 中复合文字的帖子。
  • 初始化结构体变量时不需要。初始化指针时需要它,因为指针需要一个对象来指向,而复合字面量会创建一个对象。
  • @Barmar 对象不会是 {...} 吗?为什么需要(ObjType) 来指定?
  • 您不能仅使用{...} 创建对象。那是一个初始化列表,所以它只能在初始化结构时使用。发明复合文字是为了允许创建匿名对象。

标签: c struct initialization compound-literals


【解决方案1】:

在此声明中

Car dodge = (Car) {
    .name = "Ram",
    .price = 1000
};

创建了两个 Car 类型的对象。第一个是未命名的复合文字

(Car) {
    .name = "Ram",
    .price = 1000
}

用于初始化另一个命名对象的dodge。

来自 C 标准(6.5.2.5 复合文字)

3 由带括号的类型名称组成的后缀表达式 后跟一个括号括起来的初始化器列表是一个复合 文字。它提供了一个未命名的对象,其值由 初始化列表。

其实和下面的声明类似

Car ford = {
    .name = "Ford F-150",
    .price = 25000
};

Car dodge = ford;

不同之处在于,在上一个示例中,我们创建了一个多命名对象。

来自 C 标准(6.7.9 初始化)

13 结构体或联合对象的初始化器具有自动 存储持续时间应为描述的初始化列表 下面,或具有兼容结构或联合的单个表达式 类型。在后一种情况下,对象的初始值,包括 未命名的成员,是表达式的成员。

【讨论】:

  • 两个初始化会占用相同数量的存储空间,还是创建第二个对象会加倍呢?
  • @David542 复合文字将在其定义的范围内有效。就像我写的那样,你创建了两个对象。
猜你喜欢
  • 2021-11-23
  • 2010-12-11
  • 1970-01-01
  • 2014-04-13
  • 1970-01-01
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
相关资源
最近更新 更多