在标准C中(即Post-K&R),您可以直接分配它们。下面的函数仅是为了使示例清晰,您始终只需在原地分配:
void deepCopyPerson(struct person *target, struct person *src)
{
*target = *src;
}
为了详细说明:char数组是结构体对象的一部分(真正的数组,而不仅仅是指针!),因此它们与对象一起分配和复制。
为了满足怀疑者;-)的要求,我在标准草案1570中进行了搜索:
6.5.16 赋值运算符
语义
赋值运算符将一个值存储在左操作数指定的对象中。[接下来是类型转换和排序考虑因素,这些与此处无关。]
[...]
6.5.16.1 简单赋值
约束条件
必须满足以下条件之一:
- 左操作数具有与右侧类型兼容的结构体或联合体类型的原子、限定或非限定版本;
[...]
语义
在简单赋值 (=) 中,右操作数的值会被转换为赋值表达式的类型,并替换左操作数所指定的对象中存储的值。
1 《C程序设计语言》的第一版于1978年由贝尔实验室的Brian W. Kernighan和Dennis M. Ritchie编写并出版,是第一个C语言版本的非正式语言规范,通常被称为“K&R C”,以两位书籍作者命名(与10年后规定的ANSI C进行区分)。本书第一版在第121页中包含以下句子:
关键规则是结构体能够执行的唯一操作是使用 & 取其地址,并访问其中的成员。
特别地,你不能对结构体进行赋值。(但他们继续说,“这些限制将在即将推出的版本中被取消”。)
事实上,这是ANSI版本中唯一实质性的(而不是语法上的)增加之一。Kernighan和Ritchie还准备了一本配套的“ANSI C版”书籍。这句话现在在第129页,已更新为:
唯一合法的结构操作是将其作为一个单位进行复制和赋值,使用 & 获取其地址以及访问其成员。他们详细阐述道:复制和赋值包括向函数传递参数以及从函数返回值。这种等效性在最新的C++标准中仍然成立。由于我们在C++的根管道中,下一条语句是一个必然的"结构不能比较"。有趣的是,他们添加了这个句子——显然,在引入内置赋值之后,内置比较自然而然地被提出来,但被拒绝了。在我看来,从来没有一个好的理由:如果你可以按成员方式赋值,为什么不以同样的方式进行比较呢?在许多情况下,这样做就足够了,而手动比较很难维护。在C++20中,使用
spaceship operator使这成为可能,当它(明确地)默认时,它会生成所有其他比较;确实,默认为按成员方式比较。