int a[10];
int b[10];
a = b; // illegal
typedef struct {
int real;
int imag;
} complex;
complex c,d;
c = d; //legal
[I realize that a and b are addresses in 1st case,but symbols in 2nd case]
int a[10];
int b[10];
a = b; // illegal
typedef struct {
int real;
int imag;
} complex;
complex c,d;
c = d; //legal
[I realize that a and b are addresses in 1st case,but symbols in 2nd case]
For historical info, this may be interesting: http://cm.bell-labs.com/who/dmr/chist.html
In B, declaring an array would set aside memory for the array, just as C does, but the name supplied for the variable was used to define a pointer to the array. Ritchie changed this in C, so that the name "is" the array but can decay to a pointer when used:
The rule, which survives in today's C, is that values of array type are converted, when they appear in expressions, into pointers to the first of the objects making up the array.
This invention enabled most existing B code to continue to work, despite the underlying shift in the language's semantics. The few programs that assigned new values to an array name to adjust its origin—possible in B and BCPL, meaningless in C—were easily repaired.
If at that very early stage, Ritchie had defined a = b
to copy the array, then the code he was trying to port from B to C would not have been as easily repaired. As he defined it, that code would give an error, and he could fix it. If he'd made C copy the array, then he would have silently changed the meaning of the code to copy the array rather than reseating the name being used to access an array.
There's still the question, "why hasn't this feature been added in the 40 years since", but I think that's why it wasn't there to start with. It would have been effort to implement, and that effort would actually have made that early version of C worse, in the sense of being slightly harder to port B and BCPL code to C. So of course Ritchie didn't do it.
Because C says you can't, it says "A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type", so an array can't be assigned to.
Moreover,
When you use the name of an array in a value context likea = b;
, both the names a
and b
mean
&a[0]
and &b[0]
. Often referred to as an array "decaying" to a pointer.
However, arrays are not pointers, so trying to assign an array by using pointers wouldn't make sense.
The main reason is of course the Standard. On the assignment operator constraint it says:
(C99, 6.5.16p2) "An assignment operator shall have a modifiable lvalue as its left operand"
where it defines a modifiable lvalue as
(C99, 6.3.2.1p1) "A modifiable lvalue is an lvalue that does not have array type, [...]".
So assigning to arrays is not permitted.
But the main reasons are historical reasons at the times where array copy was considered not appropriate for the hardware (the old PDP systems). Not that also in the first versions of C, the assignment of structure types objects was also not allowed. It was later added to the language but for the array to many parts of the language would have been needed to be changed to allow to assign to arrays.
The first thing to understand is that arrays are not pointers. Read section 6 of the comp.lang.c FAQ. I'll wait.
...
Ok, done? No, go back and read the whole thing.
...
Great, thanks.
Generally speaking, arrays in C are second class citizens. There are array types, and array objects, and even array values, but arrays are almost always manipulated via pointers to their elements.
This requires a bit more work for the programmer (as you've seen, you can't just assign arrays), but it also gives you more flexibility. Programs that deal with arrays usually need to deal with arrays of different sizes, even sizes that can't be determined until execution time. Even if array assignment were permitted, an array of 10 int
s and an array of 20 int
s are of different and incompatible types. If you have a fixed-size array, as in the code in your question, it's common for only some of the elements to be currently relevant; you might have a 10-element array, but you're only currently using the first 5 elements. Processing such an array element-by-element makes it easier to process only the elements that are currently active (something you have to keep track of yourself).
For a struct, on the other hand, the number and types of the members are determined when you define the type. You can't traverse the members of a struct by advancing a pointer, as you would for an array, since the members are typically of different types. Arrays and structures are different things, and they have different sets of operations that make sense for them.
There are a couple of rules in the language that try to make it easier to do this, namely:
&
(address) operator;sizeof
; andint func(char s[]);
is adjusted to a pointer parameter: int func(char *s);
.(One could argue that these rules cause more confusion than they prevent, but that's the way the language is defined.)
Now I suppose the language could have been defined, or could be redefined, so that array assignment is permitted in cases where it makes sense:
int a[10];
int b[10];
/* ... */
a = b; /* Why not? */.
Perhaps such a change could even be made without breaking existing code. But that would require another special case for the array-to-pointer conversion rule. And it would only be useful in the case of fixed-size arrays like a
and b
, which though they're quite common in introductory programming exercises, are not as common in production code.
An array name is a const pointer so you can't change what it is pointing to.
Assuming that you meant c = d on the last line is legal, it's simply copying a non-const variable to another non-const variable, which is perfectly legal.
a is actually the "pointer" to the first element of array and it's a constant "pointer", so you are trying to assign an l-"pointer".
you can achieve what are you trying to do by :
struct arraystruct
{
int t[10];
};
struct arraystruct a,b;
a=b;
EDIT:well i forgot to mention that there are a few exceptions where an array should not be considered as a pointer:
-you can use sizeof(array) but you cannot use sizeof(pointer)
-array of literal string
-a and &a are the same
That is because the kind of array you are using is a so-called static array, ie. the memory for it is on the stack. If you would use dynamic arrays (with pointers) your assignment would be legal (but a memory leak would be possible). This would be a shallow copy.