Hi Wajih-ur-Rehman,
"> The question is actually about 2D arrays. As far as I know, when a 2D
array
is declared in C++, in the memory it is actually stored as a 1D array. and
the name of the array is pointing to the first element ie. a[0][0] i.e
int a[2][2] = { {1,2},{3,4} };
Now the question is that why cant i do this
int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
int ** right?
No it is not.
Actually multidimensional arrays are treated differently when they has been
defined statically. They are array of arrays of arrays......
But it is not int** because no pointers are saved so it is not int **.
So when you do a[0] it returns one-dimensional array for the first row,
which can be cast to int *
However following are correct
int *p = &a[0];
This will fail (check it). a[0] is onedimensional array and it is already
pointer to the first element.
So what a[0] returns is address (number, constant) you cannot get the
address of a number. You can get address only of *l-values* (varaibles)
the correct is:
int *p = a[0];
Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
can get its address. So the following succeed. int *p = &a[0][0];
This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
returns its address
Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives
the same address)
It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
change the type of the returning address. now it is of type int (*)[2] which
means pointer that points to array of 2 int values.
I don't know if it is by C/C++ spec and frankly I don't believe it.
Sometimes designers of the compilers simplify the grammer in order to make
it simple and the compiler faster. This simplifications lead to some really
rear erronous constructs to go thru and compiler may not report error at all
or may report not correct error.
So I believe:
int **b = &a[0] ;
should be reported as the error "'&' requires l-value";
Indexing operator [] works differently for multidimensional arrays when they
are declared statically and dynamically:
int a[2][2]
or
int **a;
And here comes the confusion for the compiler:
This definitely doesn work:
int a = 10
int **b = &(&a);
....
compiler says correctly: *& requires l-value*
So if cout <<&a[0]; goes thru that means a[0] is l-value;
Then the following has to work as well:
int a[2][2] = {...}
int b[2] = {...}
a[0] = b;
MS VC compiler reports error: '=' : left operand must be l-value
so a[0] *is not* a l-value;
Can you see the inconsistency here.
I believe you will get different results with different compiler.
HTH
B\rgds
100