I have the following c code:
int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int **pp = &arr;
The compiler complains and I don't know why. Isn't arr a pointer points to an int array? I should be able to assign the address of it to a int**. Are there any other way to do it?
CodePudding user response:
Isn't arr a pointer points to an int array?
No, arr
isn't a pointer at all. arr
is an array. If you take the address of arr
, what you get is a pointer to an array, not a pointer to a pointer. This would work:
int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int (*pp)[8] = &arr;
// cleaner by using a type alias:
using Arr8 = int[8];
Arr8* pp = &arr;
If you want a pointer to pointer, then you must first create a pointer to which you could point at:
int* p = arr; // same as = &arr[0]
int** pp = &p;
But when I do printf("arr: %x\n", arr);. It actually prints out the starting address of arr. Doesn't that mean it is a variable stores the address of the array?
It does not mean that. arr
is the array; it doesn't store the address of the array, and the type of the variabe isn't a pointer.
When you pass an array as a variadic argument, it will implicitly convert to a pointer to first element. That is the same implicit conversion that happens in the example above: int* p = arr;
.
Note that %x
format specifier requires that the argument is of type int
(or smimilar). int*
(which is the resulting type of the implicit conversion) is the wrong type, and hence the behaviour of the program will be undefined.
CodePudding user response:
If you have an object declared like
T x;
where T
is some type specifier then a declarations of a pointer to such an object will look like
T *p = &x;
Now consider the array
int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
using this type def
typedef int T[8]:
you can rewrite the array declaration like
T arr = {1, 2, 3, 4, 5, 6, 7, 8};
So a pointer declaration to the object arr
will look like
T *p = &arr;
As the type specifier T represents the type int[8]
then a pointer to an object of this type will have the type int ( * )[8]
.
So the above declaration looks like
int ( *p )[8] = &arr;
As for the declaration
int **pp;
then it can be introduced the following way
int *p = arr;
int **pp = &p;
That is in the first declaration
int *p = arr;
the array designator arr
is implicitly converted to pointer to its first element. So the pointer p
is initialized by the address of the first element of the array arr
.
In turn the pointer pp
is initialized by the address of the pointer p
.
CodePudding user response:
Arrays and pointers are fundamentally different things:
think of an array as a street with buildings: each building has a number and the street has a name. In the definition
int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
The array namearr
is like the street name and the array elements numbered0
to7
are buildings containing each a number.a pointer is an object that contains the address to an object: a piece of paper with the address of a building:
char *p = &arr[1];
is akin to writing1, street arr
on a piece of paper. As a convenience, but rather o confusing one,char *p = arr;
is equivalent tochar *p = &arr[0];
just like telling your GPS to go to fifth street will take you to the first house on that street.a pointer to a pointer,
int **pp
is a piece of paper where you write the place where to find another piece of paper that has the address of the building in the above paragraph. This type of pointer may be required in some circumstances, but not as common as regular pointers.the definition
int **pp = &arr;
is incorrect because&arr
is not the address of a pointer. It is the address of the full arrayarr
, is a special type of pointer, like a deed is a special type of paper describing an actual property: the full extend of streetarr
, comprising pavement, sidewalks, lots and constructions erected thereupon. A pointer to a full array has a special syntax:int (*p)[8] = &arr;
It is only used in advanced C programming. Most programmers will never need one and might not even understand the syntax, just like in real life, property deeds are seldom seen outside lawyers' offices and official places and mostly abstruse to the populace.For your purpose, you can define a pointer to
int
and make it point to the beginning of the array:int *p = arr;
And if you really need a pointer to a pointer toint
, you can definepp
asint **pp = &p;
accessing the 3rd element of the array via
pp
will be written(*pp)[3]
orpp[0][3]
1.
1 among other less readable possibilities: *(*pp 3)
, *(3 *pp)
and downright obscure alternatives: 3[*pp]
, 3[0[pp]]
...
CodePudding user response:
Case 1
Here we consider the statement:
int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
The above statement creates an array named arr
of size 8
with int
elements. The type of the array arr
is int [8]
.
Case 2
Here we consider the statement:
int **pp = &arr;
The following are the things to note about the above statement:
- On the left hand side, we have a pointer to a pointer to an
int
namedpp
. That is, the type ofpp
on the left hand side isint**
. - On the right hand side, we have the expression
&arr
. Since from case 1, we know that the type of the arrayarr
isint [8]
. Therefore,&arr
isint (*)[8]
which is read as a pointer to an array of size 8 with elements of typeint
.
So essentially, the type on the left hand side is int**
(from point 1) while the type on the right hand side is int (*)[8]
(from point 2). That is, the type on the left hand side and the right hand side don't match. And this is why the compiler gives us the error saying:
error: cannot convert ‘int (*)[8]’ to ‘int**’ in initialization
Which means you're trying to initialize pp
which is an int**
with the initializer of type int (*)[8]
.
To solve this you need to make sure that the type on the left and right hand side match as shown below:
int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int (*pp)[8] = &arr; //now the type on rhs and lhs match
Now the type of pp
on the left hand side is int (*)[8]
which matches with the type of &arr
on the right hand side and hence this program work fine.
CodePudding user response:
array name is itself the address of [0] index so just make a pointer like this int *p=array_name; now just increment the pointer and access the array, like this. *(array_name i) where i could be any index which u want to access.
CodePudding user response:
It maybe the cause that the array "arr[8]" contains a value stored in the executable image (precisely ".data" section). So the pointer contains a fixed value because of optimization. And that variable is virtual (like a macro) and have not a real source. This maybe fixed by performing an operation on the "arr[8]" variable like incrementing it's pointer or making it global or creating a variable that references "arr[8]"
After that try pointing to both "pointer to arr[8]" and "arr[8]" and it may be fixed.