为何C语言中含静态数组成员的结构体可复制,静态数组却不行?
C语言数组赋值与结构体赋值差异的设计原因
先看你给出的代码示例:
typedef struct { int p[10]; } array10; int main() { array10 a = {(int[10]){...}}; array10 b = {(int[10]){...}}; a.p = b.p; // #1. 编译失败,无法赋值给int[10] a = b; // #2. 成功将b.p赋值给a.p }
这种差异完全符合C语言的核心设计逻辑,原因主要有三点:
数组的“退化”特性是根源:C语言从诞生起就为底层交互效率做了设计——数组名在绝大多数表达式场景下会自动退化为指向首元素的指针。如果允许
a.p = b.p这类直接赋值,会产生语义歧义:到底是拷贝b.p的整个数组内容,还是只把b.p退化后的指针值赋值给a.p?为了避免这种模糊,C语言直接规定数组不是可修改的左值,禁止直接赋值操作。结构体赋值的语义天然明确:结构体作为完整的用户自定义类型,它的赋值操作被定义为逐成员的浅拷贝。执行
a = b时,编译器会自动把b的所有成员(包括内部的数组p)完整拷贝到a对应的位置。结构体的名字永远代表整个对象,不会像数组那样发生指针退化,所以这种赋值安全且无歧义。C语言的“最小特性”设计原则:C语言的设计理念是只提供最必要的核心特性,避免冗余规则。既然通过将数组包裹进结构体就能实现整体赋值的需求,就没必要单独修改数组的赋值规则——这样既保持了语言规则的简洁性,又不会破坏已经广泛使用的数组指针退化特性,兼容了大量早期代码。
内容的提问来源于stack exchange,提问作者bockyboh
相关产品推荐
相关产品推荐

