#include<stdio.h>
int main(int argc , char *argv[])
{
int array[2][2] = {{1,100},{1000,10000}};
int *pointer = array;
int *ppointer = &array;
int *pppointer = array[0];
int *ppppointer = &array[0];
printf("%d\n",*pointer);
printf("%d\n",*ppointer);
printf("%d\n",*pppointer);
printf("%d\n",*ppppointer);
return 0;
}
Four pointers are point to the first element of array. which definition shown above is better? And I don't known why the same value to array and &array?
The only reason all for of your definitions compile is that your C compiler is too permitting when it comes to pointer type conversions. If you use some switches that make it more pedantic in this regard, it should immediately tell you that only the third initialization is valid, while the rest are erroneous.
In most contexts (with a few exceptions) when array of type T[N]
is used in an expression, it "decays" (gets implicitly converted) to pointer type T *
- a pointer that points to its first element. In other words, in such contexts for any array A
, the A
expression is equivalent to &A[0]
. The only contexts where array type decay does not occur are unary &
operator, sizeof
operator and string literal used as an initializer for a char
array.
In your example array
is a value of int [2][2]
type. When used on the right-hand side of initialization it decays to pointer type int (*)[2]
. For this reason this is invalid
int *pointer = array;
The right-hand side is int (*)[2]
, while the left-hand side is int *
. These are different pointer types. You can't initialize one with the other.
The
int *ppppointer = &array[0];
is exactly equivalent to the previous one: the right-hand side produces a value of int (*)[2]
type. It is invalid for the very same reason.
The &array
expression produces a pointer of int (*)[2][2]
type. Again, for this reason
int *ppointer = &array;
is invalid.
The only valid initialization yo have in your example is
int *pppointer = array[0];
array[0]
is an expression of int [2]
type, which decays to int *
type - the same type that you have on the left-hand side.
In other words there's no question of which one "better" here. Only one of your initialization is valid, others are illegal. The valid initialization can also be written as
int *pppointer = &array[0][0];
for the reasons I described above. Now, which right-hand side is "better" (array[0]
or &array[0][0]
) is a matter of your personal preference.
In order to make your other initializations valid, the pointers should be declared as follows
int (*pointer)[2] = array;
int (*ppointer)[2][2] = &array;
int (*ppppointer)[2] = &array[0];
but such pointers will have different semantics from an int *
pointer. And you apparently need int *
specifically.
Only the third actually does the right thing. All other three are invalid C++ and cause warnings in my C compiler. It is often preferable to write C that is also valid C++, because on some platforms the C++
compiler is the also recommended compiler for C also (MSVC). This also makes it easier to include C code in a C++ project without significant build-system fiddling.
Why does your compiler complain about about 1, 2 and 4? Neither of the expressions on the right hand side have the right type to be converted to int*
.
array
has type int[2][2]
it can be converted to int(*)[2]
, not int*
&array
is a pointer to an int[2][2]
array[x]
has actually type int*
&array[x]
has type int**
int *pointer = array; //Incorrect
int *ppointer = &array; //Incorrect
int *pppointer = array[0]; //Correct
int *ppppointer = &array[0]; //Incorrect
That's the short version. Now for the reasons.
The first pointer is incorrect, because you're assigning 'array' (which is a pointer without any further specification)...but not one of int, but one of int *[]
The second pointer is incorrect, since you'd be assigning the address of the pointer...essentially the address of the variable, which holds the pointer to the data.
The third one is correct, because you get a pointer to an int array, regardless of size.
The fourth one is incorrect, since you're copying the address of the first array. That makes it an int **, and not a int *.
Sorry for the many edits...I must be tired.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With