おっと
char *p="ABC";
は
少なからずのコンパイラは
const char pp[]={'A','B','C',0}
char *p=(char*)&pp[0];
と何故か解釈してくれます。
さらに「親切な」コンパイラはおせっかいにも
書き換えるとエラーになる領域にppを初期化して
くれることでしょう。
"ABC"は何故書き換えられないかという問いは
"ABC"は変数ではないから
というのが正解ですが、書き込み不能な変数
だとか書き込み不能な領域に勝手に設定するのは
一部のコンパイラです。