1) char s[] = "foo";

・まずテキストエリアに "foo" がアロケートされる
・s は "foo" の先頭アドレスで初期化される
・puts() には "foo" の先頭アドレスである所の s が渡される
・非常に自然な流れなのでオケ

2) char s[10]; s = "foo";

・まずテキストエリアに "foo" がアロケートされる
・s は char が 10 個分のデータとしてスタックにアロケートされる
・s に "foo" の先頭アドレスを代入しようとすると、ひとつ前で
スタック上にアロケートした char 10 個分はどうなるの?
・不自然な流れになるのでエラー

3) puts("foo");

・まずテキストエリアに "foo" がアロケートされる
・puts は "foo" の先頭アドレスを引数として受け取る
・非常に自然な流れなのでオケ