C中的复制数组v/s C中的复制结构 [英] Copying array in C v/s copying structure in C

查看:61
本文介绍了C中的复制数组v/s C中的复制结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C中的数组和结构将数据存储在连续的内存中.那么,为什么C不允许使用"="直接复制数组,因为结构允许这样做.示例:

Arrays and structures in C store data in memory which is contiguous. Then why is that C does not allow direct copying of arrays using "=" where as it is allowed for structure. Example:

int a[3] = {1,2,3};
int b[3];
b = a; // why is this not allowed. 

struct book b1, b2;
b1.page = 100;
b1.price = 10.0;

b2 = b1; // Why is this allowed

推荐答案

赋值要求编译器知道所赋值的类型和大小.所以形式的分配

Assignment requires that the type and therefore size of whatever is being assigned is known to the compiler. So an assignment of form

 a = b;

要求编译器知道 a b 的类型.如果类型相同(例如, a b 均为 int 类型),则编译器可以简单地复制 b a 转换为 a .如果类型不同,但允许隐式升级或类型转换,则在升级后也可以进行赋值.例如,如果 a 的类型为 long ,而 b 的类型为 short ,则 b 将隐式提升为 long ,并将提升的结果存储在 a 中.

requires that the types of a and b are both known to the compiler. If the types are the same (e.g. both a and b are of type int) then the compiler can simply copy b into a by whatever instructions it deems are most efficient. If the types are different, but an implicit promotion or type conversion is allowed, then the assignment is also possible after doing a promotion. For example, if a is of type long and b is of type short, then b will be implicitly promoted to long and the result of that promotion stored in a.

这不适用于数组,因为不一定知道数组的大小(以其元素的大小乘以元素的数量计算).一个编译单元(也就是源文件)可能有一个声明(可能包括一个头文件)

This doesn't work for arrays, because the size of an array (calculated as the size of its elements multiplied by number of elements) is not necessarily known. One compilation unit (aka source file) may have a declaration (possibly by including a header file)

 extern int a[];
 extern int b[];

 void some_func()
 {
      a = b;
 }

告诉编译器 a b int 的数组,但是它们将被定义(包括给它们一个大小)由另一个编译单元执行.然后,另一个编译单元可能会这样做;

which tells the compiler that a and b are arrays of int, but that they will be defined (which includes giving them a size) by another compilation unit. Another compilation unit may then do;

 extern int a[];

 int a[] = {3,1,4,2,3};    /*  definition of a */

和第三个编译单元可以类似地将 b 定义为27个元素的数组.

and a third compilation unit may similarly define b as an array of 27 elements.

将目标文件链接到一个可执行文件后,所有编译单元中的 a b 的用法都将相关联,并且对它们的所有操作都引用相同的对象定义.

Once the object files are linked into a single executable, the usages of a and b in all compilation units are associated, and all operations on them refer to the same definitions.

出现此问题的原因是,单独的编译模型是C的核心功能.因此,当编译器仔细查看上述第一个编译单元时,由于没有其他数组的可见性,因此它没有有关数组大小的信息.编译单元,并且需要成功或不参考错误进行诊断.由于没有有关第一个编译单元可用的任一数组中元素数量的信息,因此无法计算出要从一个数组复制到另一个数组中的元素数量.在C中的处理是,赋值 a = b 是函数 some_func()中的可诊断错误.

The problem with this comes about because the separate compilation model is a core feature of C. So the compiler, when chewing on the first compilation unit above, has no information about the size of the arrays since it has no visibility of other compilation units, and is required to succeed or diagnose errors without referring to them. Since there is no information about the number of elements in either array available to the first compilation unit, there is no way to work out how many elements to copy from one array to another. The handling of this in C is that the assignment a = b is a diagnosable error in the function some_func().

有其他方法(某些其他编程语言对这种情况的处理方式也不同),但它们通常与其他权衡取舍有关.

There are alternative approaches (and some other programming languages handle such cases differently) but they are generally associated with other trade-offs.

注意事项通常不会影响 struct 类型,因为它们的大小在编译时就已知.因此,如果 a b 具有相同的 struct 类型,则赋值 a = b 是可能的-并且可以通过(例如)调用 memcpy()来实现.

The considerations doesn't generally affect struct types, since their size is known at compile time. So, if a and b are of the same struct type, the assignment a = b is possible - and can be implemented by (say) a call of memcpy().

注意:我在上面的解释中进行了一些过分的简化,例如不考虑具有灵活数组成员(来自C99)的结构的情况.讨论此类情况将使上面的讨论更加复杂,而无需更改核心注意事项.

Note: I am making some deliberate over-simplification in the explanation above, such as not considering the case of structs with flexible array members (from C99). Discussing such cases would make the discussion above more complicated, without changing the core considerations.

这篇关于C中的复制数组v/s C中的复制结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆