3
votes

If you try that piece of code

#include<stdio.h> int main() { 


// Pointer to an integer 
int *p;  

// Pointer to an array of 5 integers 
int (*ptr)[5];  
int arr[] = { 3, 5, 6, 7, 9 };

// Points to 0th element of the arr. 


// Points to the whole array arr. 
ptr = &arr;  

printf("p = %p, address of P = %p\n", p, &p); 
return 0; }

You will get something like p = 0x7fff8e9b4370, P address = 0x7fff8e9b4340 which means the address of pointer P is something and the data inside it is another

but if you try the same with the pointer of the array like this

#include<stdio.h> int main() { 


// Pointer to an integer 
int *p;  

// Pointer to an array of 5 integers 
int (*ptr)[5];  
int arr[] = { 3, 5, 6, 7, 9 };

// Points to 0th element of the arr. 
p = arr; 

// Points to the whole array arr. 
ptr = &arr;  

printf("arr  = %p, arr address = %p\n", arr, &arr); 
return 0; } 

You will get something like arr = 0x7ffda0a04310, arr address = 0x7ffda0a04310

So how come that a pointer data is the same the pointer Address in memory ?!! when we dereference the address of the arr pointer we should get the number 3 but as i understand from this is the address location 0x7ffda0a04310 in the memory has 0x7ffda0a04310 as a data

so where i am mistaken ?

3
What type do you think int (*ptr)[5] has?jwdonahue

3 Answers

1
votes

printing p means print p's value, while p's value is address of a integer number or address of an integer array.

printing &p means you print location of p on memory.

printing arr will show address of first element of the array, it is &arr[0].

printing &arr will show location of arr on memory, it is also adress of first element of the array

So printing p will be different with printing &p. arr and &arr are different types but it will give you the same result.

1
votes

This is because when you use the symbol of an array, it actually evaluates to &arr (address to first element). So because of this arr and &arr are the same address (but not the same type!).

arr is of type int*

&arr is of type int(*)[5]

The difference is when you do pointer arithmetics. Incrementing arr will go to the address of the next element. So *(arr+1) is essentially the same as arr[1]. Incrementing &arr jumps over the whole array (incrementing a pointer always jumps the whole size of the type)

1
votes

What you've discovered is that the address of an array is the same as the address of its first member.

When you use the array arr in an expression, in most cases it decays to a pointer to its first element. So arr in an expression is equivalent to &arr[0]. Since the members of arr have type int, the expression &arr[0] (and by extension arr) have type int *.

In some cases however this decay does not happen. One of those is when an array is the operand of the & operator. So the expression &arr has type int (*)[5], i.e. a pointer to a array of int of size 5.

As for why the values of these two address are the same, it makes sense if you look at it:

                  arr 
                -------
0x7ffda0a04310  |  0  |
                -------
                |  0  |
                -------
                |  0  |
                -------
                |  0  |
                -------
0x7ffda0a04314  |  1  |
                -------
                |  1  |
                -------
                |  1  |
                -------
                |  1  |
                -------
                ...

Looking at this, you can see that the array itself and the array's first element start at the same address.

So arr (as an expression) has type int * while &arr has type int(*)[5], but both have the same value.