2008-07-09 [長年日記]
>> [チラシの裏] ポインタと配列の違い 

経由のネタ。
ポインタと配列の違いを述べれるほどにC言語の仕様を読んだことがないし、 慣習に慣れ親しんだこともない。 なのでC言語における「ポインタ」って何だっけ、みたいなとこでまずつまずく。 「『ポインタ変数』と『ポインタ』は同一概念なの?」とかで。
あー「ポインタ」は(「配列」も)型か。
型の違い、ということで類似した問い 「整数型と浮動小数点型の違いがはっきりわかる事例を挙げよ」だったら、 たとえば「整数型は配列参照に使えるけど、浮動小数点型は無理」みたいな 回答がある。
これを踏まえて元の問いについて考えると、 「ポインタは関数のパラメータになれるけど配列は無理」みたいな 回答を思いつい。
けど、そーゆーことが問われてるわけじゃないよな。
「Aの配列」型のモノが評価*1される際に「Aへのポインタ(その配列の先頭要素を指す)」だと読み替えられるケースもあるけど、そうでないケースもあるよ
という話において「そうでないケース」を示せ、という問い……でもない気もする。
sizeof 演算子の被演算数のときとかが「そうでないケース」だよね。
あーやっぱ上の文脈で使うべき語は「評価」ではないな。 むしろ「配列型は評価するとポインタ型になるよ。/sizeof 演算子は被演算数を評価しないよ」みたいな文章の方が感覚と一致するもん。代入演算子の左辺値とか評価してどーするみたいな。 あくまでオレ用語としての話、な。
もちろん「『ポインタ』と『配列』は、名前が違います><」とかも聞かれてない。
上で言う「読み替えられるケース」の方で、
生粋のポインタと読み替えられたポインタはどっちもポインタなのに 振る舞いが違うことがあるよ。それはどんな時かな?
という問いだとも考えられて、回答例として
char array[] = "abc"; char *pointer = "abc"; array[0] = 'A'; pointer[0] = 'A'; /* 何か使う */
みたいのをしたら pointer の方が SEGV る、というありえるけど、 これってちょー複雑な気がするのね。
「ちょー」は言いすぎかも。
- 文字列リテラルの変更は未定義*2だから、両方の例が同じように見えるように動作することもありえるよねとか、
- SEGVったにしても「初期化の動作の違い」と「文字列リテラルの変更」のコンボだから説明がめんどいよねとか、
- 例として char 型に特化しすぎてね? 「char の配列を文字列リテラルで初期化できる」って特例じゃねとか、
ポインタと配列の違いを示すための例にしては、 いろんな要素が出てきて説明するのがめんどい、みたいなことを思った。
あーあと話はズレるけど、どのくらい低いレイヤまで「C言語」の範囲なんだっけ とかゆーのも分かってない。
asm は意味付けされた予約語なのか、予約だけしてある予約語なのか、 処理系が(勝手に)導入してるモノなのか、とか。
リンク(というか分割コンパイル?)って概念はあるんだっけ、とか。 ファイルを分けるのはスコープを切るための道具でしかない? あー C インタプリタとかもありえるから、 「リンクって何ですか><」とゆー話だよな。