两个结构初始化之间的区别

Posted

技术标签:

【中文标题】两个结构初始化之间的区别【英文标题】: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 中复合文字的帖子。 初始化结构体变量时不需要。初始化指针时需要它,因为指针需要一个对象来指向,而复合字面量会创建一个对象。 en.cppreference.com/w/c/language/compound_literal @Barmar 对象不会是 ... 吗?为什么需要(ObjType) 来指定? 您不能仅使用... 创建对象。那是一个初始化列表,所以它只能在初始化结构时使用。发明复合文字是为了允许创建匿名对象。 【参考方案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 复合文字将在其定义的范围内有效。就像我写的那样,你创建了两个对象。

以上是关于两个结构初始化之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

以下两个c语句之间的区别[重复]

C#:关键字out和ref之间的区别

“#include&lt”和#include之间的区别[关闭]

ArrayList和LinkedList内部是怎么实现的?他们之间的区别和优缺点?

阿里《JAVA开发手册》为什么建议设置HashMap的初始容量,设置多少合适

指针与引用