これ、結構tricky。

コメント欄にある「K&Rの5.3を読めばわかる」かというと多分わからない。それどころか

P. 100
char s[];
and
char *s;
are equivalent;

なんて書いてあるから余計わからなくなると思う。

なのだけど、すっごく簡単な覚え方がある。

答えは

sの値を変更できるか

要するに

char *s = "pointer";
printf("%s\n", ++s);

はOKだけど、

char s[] = "array";
printf("%s\n", ++s);

はNGということ。GCCなら

error: wrong type argument to increment

というエラーが出るはず。

実は、このことはK&Rにも書いてはある。

P. 99
There is one difference between an array name and a pointer that must be kept in mind. A pointer is a variable. so pa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal.

んだけど、この5.3はポインターと配列の同値性(equivalence)をむっちゃ強調しているので、このパラグラフは簡単に読み落とされちゃう。K&Rで一番罪作りな項なんじゃないか。

Dan the Occasional C Programmer