Assumed a little endian architecture where an int is 32 bits (4 bytes), the individual bytes of int arr[] look like this (least significant byte at the lower address. All values in hex):
|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00
char *ptr = (char *) arr;
Now, ptr points to the first byte - since you have casted to char*, it is treated as char array onwards:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- ptr
Then, *(ptr+4) accesses the fifth element of the char array and returns the corresponding char value:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- *(ptr + 4) = 2
Hence, printf() prints 2.
On a Big Endian system, the order of the bytes within each int is reversed, resulting in
|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
^
+-- *(ptr + 4) = 0