配列とポインタの交換性が理解できればそんなに難しく無い。
p[i]というのは*(p + i)のシンタックスシュガーということがわかれば同じ動きをする
コードを配列とポインタで書いてみれば理解できると思う。

文字列リテラルも実際は先頭のポインタをもっていてそれを渡すと'\0'までを文字列とする
とわかれば混乱しないだろう。

653の配列版(ちなみに653はコピペすると全角スペースのせいでそのままじゃコンパイルが通らない)
#include <stdio.h>
int main(void){
char *p = "ABC";
int i;
for (i = 0; p[i] != '\0'; i++)
printf("[%p] => [%c]\n", &p[i], p[i]);
return 0;
}