My answer may be not professional enough. FYI :-) (poor english)
when you dereference a pointer, the type of it is important.
We know that int takes up 4 bytes of memory while char does only 1.
One example are as followed:
(%x: print in hex)
#include <cstdio>
#include <cstdlib>
The output on my pc is:
a: -1412567278
in hex:
a: abcdef12
ptc_a: 61fdfc
pti_a: 61fdfc
*ptc_a: 12
*pti_a: abcdef12
*(ptc_a + 1): ffffffef
c: V
in hex:
c: 56
ptc_c: 61fdfb
pti_c: 61fdfb
*ptc_c: 56
*pti_c: cdef1256
*(ptc_c + 1): 12
In this program, varibles a and c are storaged like this:
address | values, type
0x61fdff | ab, int High address
0x61fdfe | cd, int
0x61fdfd | ef, int
0x61fdfc | 12, int <- ptc_a, pti_a
0x61fdfb | 56, char Low address <- ptc_c, pti_c
When you print *ptc_a, it shows 12, which is only 1 byte long in 0x61fdfc.
Similiarly, when you print *pti_c, it shows cdef1256, which takes up 4 bytes from 0x61fdfb to 0x61fdfe. a and c are all storaged in stack from high to low address. However, data of a are in an inverse order. 0x61fdfc is the highest of a and 0x61fdff the lowest.
So, in your example, ptr_i actually reads the data of c as well as a, because ‘A’ is only a 1-byte data. And dereference of it cause the data loss. On the contrary, ptr_c only reads the lowest byte of a(65), and a happens to only need one byte to store, so when you dereference ptr_c, you get exactly 65.
I'm a beginner in programming so if there's a mistake please let me notice.