Assuming little-endian and that int is 4 bytes then 2 is probably stored as 00000010 00000000 00000000 00000000 in memory. The original char pointer p will point to the first byte which is 00000010 and that will be interpreted as the value 2. After incrementing the pointer p it will point to the second byte which are all zero bits so it will be interpreted as the value 0.
It maybe easier to understand if you initialise and print the values in hexadecimal. The reason for that is that a single byte of memory can be represented by a pair of hexadecimal digits.
1 2 3 4 5 6 7 8 9 10 11
#include <stdio.h>
int main()
{
int arr[3] = {0x12345678, 3, 4};
char *p = (char*) arr;
for (unsignedint i=0; i<sizeof(arr); i++)
printf("%02x ", *p++);
}