First edit is int i = 0; //else unexpected results due to garbage value.
char *p=(char *)&i;
++p;
In memory int i is stored as : [0000 0000] [0000 0000] [0000 0000] [0000 0000] --> Assuming Little endian system (Right to Left is LSB to MSB ) and int size as 4 bytes.
Here first char pointer p is made to point i but typecasted to char pointer so will fetch only 8 bits from LSB of int i.
++p; makes p point to next byte. Then p will point to highlighted bit below i.e from there next 8 bits as char is of size 1 byte.
[0000 0000] [0000 0000] [0000 0000] [0000 0000]
(*p)=2;
This makes changes in memory as follows :
[0000 0000] [0000 0000] [0000 0010] [0000 0000]
Now if we try to print i its nothing but 512 as 9th bit from LSB is 1.
So output is 512.