I am learning C programming language, I have just started learning arrays with pointers. I have problem in this question, I hope the that output must be
int main(){
int arr[] = {1,2,3,4,5};
char *ptr = (char *) arr;
printf("%d",*(ptr+4));
return 0;
}
Each case of arr
has sizeof(int)
size (which may be 4 on your implementation).
Since ptr
is a pointer to char
, pointer arithmetic makes ptr + 4
points 4 bytes after &arr[0]
, which may be &arr[1]
.
In memory, it looks like something like:
Address | 0 1 2 3 | 4 5 6 7 | ...
Value | arr[0] | arr[1] | ...
int main(){
int arr[] = {1,2,3,4,5};
char *ptr = (char *) arr;
printf("%d",*(ptr+4));
return 0;
}
Imagine arr
is stored at the address 100
(totally dumb address). So you have:
arr[0]
is stored at the address 100.
arr[1]
is stored at the address 104. (there's is +4 because of the type int
)
arr[2]
is stored at the address 108.
arr[3]
is stored at the address 112. Etc etc.
Now you're doing char *ptr = (char *) arr;
, so ptr
= 100 (the same as arr
).
The next statement is interesting, specially the second argument of printf
: *(ptr+4)
.
Keep in my mind that ptr
= 100. So ptr + 4
= 104, the same address that arr[1]
! So it will print the value of arr[1]
, which is 2.
On a 32 bit platform, int
is four times the size of char
. When you add 4 to ptr
, you add 4 times the size of what ptr points to to ptr (which itself is a memory location). That happens to be the address of the second element in the int
array.
On a 64 bit platform, int
is eight times the size of char
; and your output would be very different.
To cut a long story short, your code is not portable, (also see Joachim Pileborg's answer re endianness) but amusing to unpick.
Assumed a little endian architecture where an int is 32 bits (4 bytes), the individual bytes of int arr[]
look like this (least significant byte at the lower address. All values in hex):
|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00
char *ptr = (char *) arr;
Now, ptr
points to the first byte - since you have casted to char*
, it is treated as char array onwards:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- ptr
Then, *(ptr+4)
accesses the fifth element of the char array and returns the corresponding char
value:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- *(ptr + 4) = 2
Hence, printf()
prints 2
.
On a Big Endian system, the order of the bytes within each int
is reversed, resulting in
|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
^
+-- *(ptr + 4) = 0
Since you are coverting int* to char*, ptr[0] = 1, ptr[4] = 2, ptr[8] = 3, ptr[12] = 4 , ptr[16] = 5 and all others equal to 0. ptr+4 points to 4th element in the ptr array. So result is 2.
It's because the size of char
is one, and the size of int
is four. This means that adding 4
to ptr
makes the result point to the second entry in the int
array.
If you compiled this on a big endian system you would have printed 33554432 instead.