②型モデル
宣言はいつでもリストで似たような図をかける。
上の例で言えば
int(*func[10])(int a);
という宣言があったら、これを
fanc is array[10] of pointer to function(a is int) returning int.
fancはint型を返す関数(aはint)へのポインタの配列[10]
とよめた。ではリストで図示してみると、
___ 返す____ への ________ の________ int| →|関数| → |ポインタ| →|配列 |  ̄ ̄ |int |  ̄ ̄ ̄ ̄ |要素10 |  ̄ ̄  ̄ ̄ ̄ ̄
こんな具合である。
K&Rではオブジェクトの生成法は一般的に再帰的に適用可能である。
とあり、つまり大概の宣言はどんどん繰り返してくっつけていけますといっている。
この先頭を基本型と呼び、常にintやcharなどの型が来る。
そして2つ目以降を派生型とよぶ。
派生型は考えれば分かるが関数、ポインタ、配列、構造体、共用体がある。
また、最後の型(上の場合では配列[10])は型全体がどんなものか決めるもので、他に対し特に重要な意味を持っているので型分類と呼ぶ。
[型]不完全型
Cの型分類は
- オブジェクト型
- 関数型
- 不完全型
不完全型とは方のサイズが決まらない型の中で、関数型以外のものを指す。
逆にサイズが特定できるものを「オブジェクト型」と呼ぶ。
典型例として構造体のタグ宣言が挙げられる。
例えばこんな感じである。
struct a{ struct b *bb; }; struct b{ struct a *aa; };
こうなった時、どちらを先に宣言しても宣言がないと言われるだろう。
対処法はもちろんある。
#include<stdio.h> main(){ struct b; //*タグだけ先に宣言*// struct a{ struct b *bb; }; struct b{ struct a *aa; }; }
とタグだけ先に宣言してやると良い。
タグだけ宣言された時点ではその内容が分からない。
もちろんサイズも決められない。このような型を不完全型という。
サイズが決められないことにより、不完全型は変数や配列を取ることが出来ない。
ただしポインタだけは取ることが出来る。
又、関数型はサイズが特定できない。ということは上の「不完全型は変数や配列を取ることが出来ない。ただしポインタだけは取ることが出来る。」という言葉を当てはめると
関数型はポインタ型以外に派生できない。
という結論に達する。
不完全型とは方のサイズが決まらない型の中で、関数型以外のものと最初に述べたが、少し他と仕様が違うところがあるからである。
つまり、関数は引数の型を持つので関数は関数型と特別のものになる。
fanc(int a)←aが引数。