Pointers should be printed with %p
not %d
: the number might be too big and so it is overflowing.
EDIT
Let me be clearer on this: types such as int
char
etc. have a fixed number of bits/bytes. Even if two types have the same number of bits the difference is how the computer interprets them. For integers, including characters, with n
bits can represent 2^n
values. Signed integer use some of this to represent negative numbers: particularly you can represent the number in the range -2^(n/2)
to 2^(n/2) - 1
. On the contrary unsigned int represents numbers from 0
to 2^n - 1
. The biggest integer has all bits set to 1 except the msb. To get the correspondent positive number the steps are exactly the same
Negative numbers are calculated using Two's complement: you take the bit-representation of the positive number, do a bit-per-bit negation and then sum 1 to the result. Negative numbers have the most significant bit set to 1.
Let's consider 2 bits: you can represent 4 values with it. If you use an unsigned representation the binary number 10
corresponds obviously to 1
. On the contrary if you interpret it as a signed number its value is -2
.
Another example is the following consider for example an integer with 8 bits: 00001011
. This is a positive number. Suppose you cast it to an integer type of smaller size, for example 4 bits. According to this answer, the most common behaviour, which is actually implementation dependent, is to discard the most significant bits. So your number will become 1011
but using an int
representation it is now considered a negative number.
You might try to print is as an unsigned %u
:
printf("%u %u %u",(unsigned int)(p),(unsigned int)(q),(unsigned int)(r));
Also note that I am getting the warning: warning: incompatible pointer types initializing 'int *' with an expression of type 'int (*)[2]' [-Wincompatible-pointer-types]
for
int *q = &a;
EDIT
For example in this program run on my computer returns a size of 8 byte for pointers (of type int
) and 4 bytes for int
:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
printf("size of int*: %lu\n", sizeof(int*));
printf("size of int: %lu\n", sizeof(int));
return 0;
}
From this it seems you are following in the second case of the examples I gave.
PLEASE NOTE Being the pointer size bigger, also the cast to unsigned int
might not be enough.