ここが変だよC言語 - わさっきで付箋箇所のリクエストをいただき,さらに著者の一人からメールで問い合わせがありましたので,昨日,本を確認しました.
読みながら,なんでこんなところにつけたのか,分からないものは,付箋を外しました.逆に,付箋をつけたところもあります.
昨日付箋をつけたところから,一つ.
上p.160にあるarray09.c*1ですが,手元の環境では,2行目の出力は
size of &a = 4 bytes
となりました.コンパイラは「gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)」です.コンパイルオプションに,-std=c99,-std=gnu99,-ansiなどを入れても,みな同じ結果でした*2.
このプログラムを追試したきっかけは,数ページあとの,以下の記述でした.
「aと&aは同じで配列の開始アドレスである」とはダブルスタンダードもはなはだしい.&a[0]が開始アドレスを返すのは自然である.』
(p.164)
この主張で,aはポインタ値として使用されている配列変数*3という前提があります.そのもとで,「同じ」には同意できません.これ,直感に合いませんThat's against my instinct.というのも,aと&aについて,アドレスの値は等しいのですが,型が異なるからです.char a[100];と宣言した場合,char *b = a;そしてchar (*c)[100] = &a;と代入することができますが,このaと&aを逆にすることはできません.
なので,「配列変数」と「&配列変数」は,別物ととらえるべきです.
著者は,array09.cの実行結果を根拠として,aと&aを「同じ」とみなしています.この問題,処理系依存でしょうか.
もうひと工夫.array09.cの途中に
printf("size of (&a)[0] = %d bytes\n", sizeof((&a)[0]));
を追加すると,この出力は
size of (&a)[0] = 100 bytes
でした.「(&a)[0]」とaが同じであること,そして&aとaが異なるものであることの傍証になる*4と思います.