@mint: I don't have a concrete answer on that, but I don't think address is being typecasted. I think address will remain same. Address of i can be held in a pointer to integer, but since we need it to be assigned it to pointer to char, we typecast the pointer. You can think like address of i is implicitly pointed to by a pointer to int, which you need to typecast to pointer to char.
You can try checking the output of following:
printf("%p %p %p %p %p", p, p+1, &i, ((char *) &i) + 1, &i + 1);
&i + 1 gives the next address according to the size of integer.
((char *) &i) + 1 gives the next address according to the size of char.
So, before type coversion, the pointer would have pointed to full int size block ( say 4 bytes ), now it will point to char size blocks (1 byte).