tags:

views:

98

answers:

4
int i=40;
char *p;
p=(char *)&i;//What actually happens here?
printf("%d",*p);

What will be the output? Please help!

+1  A: 

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;

org.life.java
Except that the machine might be big endian in which case, you'll get 0.
JeremyP
+2  A: 
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.

sepp2k
Most likely that would be either 0 or 40 (depending on endianness of the machine).
Tadeusz A. Kadłubowski
A: 

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.

Patrick
A: 

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.

John Bode