Let's calculate (*(*(*p)[1] - 2))
Assume arr is stored at address 100.
p = &arr,
p points to location 100 and type is pointer to array[2][3][3] of char.
Let's calculate (*p)[1]:
Since p points to address 100, *p would point to address 100 too (but scale differently).
Let p1 = *p, so above expression becomes:
(*(*p1[1] - 2))
p1 points to address 100 and has type pointer to array[3][3] of char.
p1[1]
== p1 + 1 * sizeof(*p1)
== p1 + 1 * sizeof(char[3][3])
== p1 + 9
== 109.
Let p2 = p1[1], so above expression becomes:
(*(*p2 - 2))
After removing the redundant paranthesis it is:
*(*p2 - 2)
where p2 points to 109 and has type pointer to array[3] of char.
Let p3 = *p2, ie p3 points to location 109 and has type pointer to char.
The above expression becomes:
*(p3 - 2)
p3 - 2
== p3 - 2 * sizeof(*p3)
== p3 - 2 * sizeof(char)
== p3 - 2 * 1
== p3 - 2
Since p3 points to location 109, p3 - 2 would end up being location 107.
Hence *(p3 - 2) would be value at location 107, ie, at 7 bytes from arr which equals 'E'.
So the value of the expression: (*(*(*p)[1] - 2)) would be 'E'.
Similarly value of the expression (*(*(*p[0] + 1)) would be 'A'.
'E' - 'A' == 69 - 65 == 4.
Hence the output should be 4