int i=40;
char *p;
p=(char *)&i;//What actually happens here?
printf("%d",*p);
What will be the output? Please help!
int i=40;
char *p;
p=(char *)&i;//What actually happens here?
printf("%d",*p);
What will be the output? Please help!
here you are
int i = 40;
//allocating memory for integer i and assigning value 40 to it
char *p = (char*)&i;
so here you are defining a pointer variable and assigning it the address of i after casting it to char*
suppose i
is allocated at 1021 address
so p will have that address with the limit of 1 byte so it should hold first 8 bit from the representation of 40;
as 40 has been cover under first 8 bit of 2 byte it will hold a char equivalend of 40 but as you are printing it with %d
it shopuld print 40
;
p=(char *)&i;//What actually happens here?
It takes the address of i
and casts it to a char
pointer. So the value of *p
is now the first byte of i
. What that value is, is platform dependent.
It depends. On Windows, the output will be 40, but this is just because of a lot of coincidences:
First of all, printf does not (cannot) check the type of its arguments, so since it sees %d in the format string, it assumes that the given argument is an int. Although *p is only a char, the result is promoted to an int (as is for every argument that is not specified in the function prototype).
Second, p will point to the memory taken by the variable i, but since it's a char pointer, it will only take one byte from the memory of i. Since Windows/Intel uses Least-Significant-Byte first convention, 40 will be stored as byte pattern "40 0 0 0" so, since *p takes the first byte (char), the result will be 40. If i would have the value 256 or bigger, the result would be incorrect.
Let's start by looking at how the contents of i
and p
would be laid out in memory (assuming big-endian order):
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---------------------- i 0x08000000 0x00 0x00 0x00 0x28 p 0x08000004 0x?? 0x?? 0x?? 0x??
Since p
is being declared as an auto variable, it's not initialized to anything and contains a random bit pattern represented by 0x??
.
In the line
p = (char *)&i;
the expression &i
evaluates to the address of i
, or 0x08000000, and its type is pointer to int
, or int *
. The cast converts the type from int *
to char *
, and the result is assigned to p
.
Here's how things look in memory after the assignment:
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---------------------- i 0x08000000 0x00 0x00 0x00 0x28 p 0x08000004 0x08 0x00 0x00 0x00
So the value of p
is now the address of i
. In the line
printf("%d", *p);
the type of the expression *p
is char
, and its value is whatever is stored in address 0x08000000, which in this particular case is 0. Since printf
is a variadic function, the value of *p
is promoted from type char
to type int
.
So for this particular case, the ouput is "0". If the order were little-endian, the map would look like
Item Address 0x03 0x02 0x01 0x00 ---- ------- ---------------------- i 0x08000000 0x00 0x00 0x00 0x28 p 0x08000004 0x08 0x00 0x00 0x00
and the output would be "40".
Note that this whole example assumes that integer and character pointers have the same size and layout; that's not guaranteed to be true everywhere (see the Online C Standard (n1256 draft), section 6.2.5, paragraph 27), so you can't rely on this working everywhere the way you expect (assuming I'm correct in thinking that int
and char
are not compatible types as defined by the standard, but I could be wrong on that). Type punning in general is not safe.