Copying array in C v/s copying structure in C

自作多情 提交于 2020-07-10 11:55:38

问题


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

回答1:


For the first question

You cannot directly write to an array, you can write only to the individual cells to an array. You can use a for loop to initialize array b or memcpy(&b, &a, sizeof b);

And with the structs the compiler does the memcpy for you.

Correct me if I am wrong.




回答2:


When you type : b=a , the compiler expects that you are assigning an array to b, but a is just a pointer to the location where the first element of the array is stored so there is a type mismatch.This is why printf("%d",*a); will print 1. And as for why structures can be assigned, it is because b1 and b2 in the above example are basically variables of the datatype book and variables can be assigned.When variables are assigned the contents are copied and they don't refer to the same memory location.This example might explain what i am saying more clearly:

#include<stdio.h>

typedef struct{int a;}num;
int main()
{
    num b,c;
    b.a = 10;
    c=b;
    b.a =11;
    printf("%d\n",(c.a));
    return 0;
}

The output is 10. This proves that b and c in this example do not point to the same memory.hope this helps.




回答3:


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;

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;
 }

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 */

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

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.

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.

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().

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.



来源:https://stackoverflow.com/questions/18296224/copying-array-in-c-v-s-copying-structure-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!