在 * 简单赋值 *(=)中,右操作数的值转换为赋值表达式的类型,并且替换左操作数指定的对象中存储的值。 1 The first edition of The C Programming Language,由贝尔实验室的Brian W. Kernighan和Dennis M. Ritchie编写,于1978年出版,是第一个C语言版本的非正式语言规范,通常被称为"K & R C",以该书的两位作者的名字命名(并作为与10年后指定的ANSI C的区别)。该书的第一版在第121页包含以下句子: 基本规则是,您可以对结构执行的唯一操作是用&获取其地址,并访问其成员之一。 特别是,您不能分配结构。(但他们继续"这些限制将在即将到来的版本中删除"。) 事实上,这是10年后通过的ANSI版本中为数不多的对语言的实质性(相对于语法)补充之一。Kernighan和Ritchie准备了一个随附的"ANSI C版"。这句话,这次在第129页,现在读作: 结构上唯一合法的操作是**将其作为一个单元进行复制和赋值,使用&获取其地址,并访问其成员。 他们详细说明: 复制和赋值包括向函数传递参数以及从函数返回值。 这种等价性在今天最新的C标准中仍然成立。 既然我们现在是在C的根管里:下一个语句是一个绝对的"Structures may not be compared."**有趣的是,他们添加了这句话--显然,内置比较在引入内置赋值之后出现了,但被拒绝了。在我看来,这从来没有一个好的理由:如果你可以按成员分配,为什么不也用这种方式比较呢?在很多情况下,这就很好了,而且手动比较很难维护。又花了30年的时间才在C++20中用spaceship operator使之成为可能,spaceship operator在(显式)默认时生成所有其他比较;实际上,它默认为成员间比较。
4条答案
按热度按时间deyfvvtc1#
Post-K & R(即在标准C中)1你可以直接赋值。下面的函数只是为了让例子更清楚,你总是直接赋值:
详细说明:char数组是struct对象的一部分(真正的数组,而不仅仅是指针!),因此与对象一起分配和复制。
为了满足不信者;- )我在1570年的标准草案中四处挖掘:
赋值运算符将一个值存储在左操作数指定的对象中。[后面是类型转换和排序注意事项,与此无关。]
[...]
应满足以下条件之一:
[...]
在 * 简单赋值 *(=)中,右操作数的值转换为赋值表达式的类型,并且替换左操作数指定的对象中存储的值。
1 The first edition of The C Programming Language,由贝尔实验室的Brian W. Kernighan和Dennis M. Ritchie编写,于1978年出版,是第一个C语言版本的非正式语言规范,通常被称为"K & R C",以该书的两位作者的名字命名(并作为与10年后指定的ANSI C的区别)。该书的第一版在第121页包含以下句子:
基本规则是,您可以对结构执行的唯一操作是用&获取其地址,并访问其成员之一。
特别是,您不能分配结构。(但他们继续"这些限制将在即将到来的版本中删除"。)
事实上,这是10年后通过的ANSI版本中为数不多的对语言的实质性(相对于语法)补充之一。Kernighan和Ritchie准备了一个随附的"ANSI C版"。这句话,这次在第129页,现在读作:
结构上唯一合法的操作是**将其作为一个单元进行复制和赋值,使用&获取其地址,并访问其成员。
他们详细说明:
复制和赋值包括向函数传递参数以及从函数返回值。
这种等价性在今天最新的C标准中仍然成立。
既然我们现在是在C的根管里:下一个语句是一个绝对的"Structures may not be compared."**有趣的是,他们添加了这句话--显然,内置比较在引入内置赋值之后出现了,但被拒绝了。在我看来,这从来没有一个好的理由:如果你可以按成员分配,为什么不也用这种方式比较呢?在很多情况下,这就很好了,而且手动比较很难维护。又花了30年的时间才在C++20中用spaceship operator使之成为可能,spaceship operator在(显式)默认时生成所有其他比较;实际上,它默认为成员间比较。
wr98u20j2#
要对包含数组(不带任何指针)的结构执行深层复制,深层复制非常简单
但是如果“字符串”是指针的话就不行了,必须分配新的字符串,然后使用strcpy()这样的函数来复制成员。
上面遗漏了一些错误检查(例如,需要在复制之前检查
malloc()
是否成功)。sigwle7e3#
strcpy()
和strdup()
之间存在差异。strdup()
分配空间并返回一个指向字符串副本的指针,您还必须free()
返回的指针。strcpy()
获取分配的空间并将字符串复制到其中。在您的例子中,它似乎是
strcpy()
,因为您的结构的字段不是指针,所以您不能为它们分配一个指向已分配空间的指针,而这是strdup()
返回的结果。但是,正如this answer中所解释的,实际上您不需要这样做。
mtb9vblg4#
如果你使用
strcpy()
,你必须自己分配内存。strdup()
会为你做这件事。你可以使用任何一个来创建一个新的内存块,它与原来的内存块是分开的,但是strdup()
自然更简单,因为它不需要一个单独的malloc(strlen())
调用。