Why pointer variable can be assigned value but array variable can't ? In other words, why statement 4 is illegal is below code snippet ?
1.int a[10];
2.int *p;
3.p=a; //legal operation
4.a=p; // Illegal operation
Why pointer variable can be assigned value but array variable can't ? In other words, why statement 4 is illegal is below code snippet ?
1.int a[10];
2.int *p;
3.p=a; //legal operation
4.a=p; // Illegal operation
There is a reason why your statement 3. is called decay. The conversion is one way, because pointers and arrays are not the same.
When array decays to a pointer, it loses information about it's size. It cannot be regained, so the opposite conversion cannot be performed implicitly. I.e. to int[WHAT]
should it convert back?
Two main differences from the top of my head:
If you check a
does contain information about it's size, pointer does not. Check sizeof(a)
, sizeof(p)
, and sizeof(*p)
.
a
guarantees that some elements are there (c++ forbids zero size arrays).
But it makes sense to treat p
as unbound array of type decltype(p)
in some contexts. Particularly the placement of elements is easy to compute placement of a given element in memory. It is the same as pointer arithmetic. That is why the notation is the same e.g. both p[6]
and a[6]
work. So the functions accepting arrays, can accept arrays of arbitrary sizes.
But it is not the same.
The differences become apparent when you add another dimension. With a (fixed size) array, you can compute placement of element arithemtically just as above, it is contiguous in memory, and you know size of each "row".
But for int**
you have two levels that you don't know boundaries. I.e. you are not able to compute arithmetically the position of element in int**
you have to resolve 1st level, and then use calculation. Each "row" can have different length.
That is why you get errors looking like:
main.cpp:11:8: error: cannot convert 'int**' to 'int ()[5]' for argument '1' to 'void f(int ()[5])'
Note that 1st dimension got covnerted to a pointer, but you can unbind array only on one dimension (by convention it is the 1st)!
See http://coliru.stacked-crooked.com/a/5063a9d19739278a:
void f(int a[3][5]){}
int main() {
int ** p = new int*;
int b[4][5]; // works because 1st dimension can decay to pointer (unbound array)
int c[3][6]; // doesn't work because 2st dimension cannot decay to pointer
f(p); f(b); f(c);
return 0;
}
There are some quirky things about how arrays work, but the main things are:
Based on the details of how arrays are defined, it makes some sense to convert from the first to the second, by converting the array into a pointer to its first element (and the language mandates that this conversion happens implicitly), but it doesn't make much sense to convert from the second to the first.
you can think of an array as a pointer that reserves several locations in memory. a
is the pointer to array a. when you use p=a
you are assigning to pointer p the pointer that points to array a. but you cannot use a=p
since a is more than one object and p points to a single location
int * p
Technically this is either the adress of one integer or the adress of an array, whose we ignore the size (MAYBE more than 10)
int a[10];
This is an object of a given size
Therefore you cannot asign an adress to a full object.
Using p=a
you are assigning the base address of an array to a pointer so it is legal or you can write p=&a[0];
but a=p doesn't make any sense it is not a single location.
Basically they [arrays and pointers] are just different entities. Pointer can point to the first element of the array and array in certain circumstances will decay to a pointer (you can refer to the C++ language standard 4.4.2), but not vice versa.
See also this answer.