電脳ミツバチのコンピュータ広報室

銀座の屋上菜園を耕しています。コンピュータ畑も耕します。

②Cの宣言解読

スポンサーリンク

前橋和弥氏の書いた「C言語ポインタ完全制覇」では非常に面白い宣言の解読法がある。

ややこしい宣言は英語で読め。

というものである。

  1. int *f(); /*f:intへのポインタを返す関数
  2. int (*pf)(); /*pf:intを返す関数へのポインタ

と書かれても一行目は何とか読めても2行目がよく分からない。
2行目のpfの宣言を英語で読むと
pf is pointer to function returning int
(pfはintを返す関数へのポインタ)
と読める。
機械的に読む方法を載せる。

  1. まず、識別子に着目する(変数名や関数名)
  2. 続いて識別子に近いほうから優先順位に従って派生型(ポインタ、配列、関数)を解釈する。優先順位について少しだけ述べると(これだけ抑えれば読める。)
    1. 宣言をまとめるための括弧
    2. 配列を意味する[],関数を意味する()/*関数なら引数解釈に入る*/
    3. ポインタを意味する*
  3. 派生型を解釈したら、それを「of」または「to」または「returning」で連結する。
  4. 最後に、型指定子(左にあるintやdouble)を追加する。
  5. 日本語で解釈する。(逆から読む!)

と言うものであった。
非常に有用なので是非活用すると共に前橋氏に感謝する。

int hoge[10][3];

hoge is array[10] of array[3] returning int.

int *hoge[10];

hoge is array[10] of pointer returning int.
ホゲはint型を返すポインタの配列[10]。

int (*hoge)[3];

hoge is pointer of array returning int.
ホゲはint型を返す配列[3]のポインタ

int(*func_p)(double)

まずfunc_pに着目。
宣言をまとめる括弧の中を見る。[is]
続いて*をみる。[to]
次に関数を意味する()をつける。[()の中を解釈]
関数の引数の中(double)を見る。[returning]
最後に左端の型指定子を追加する。
func_p is a pointer to function(double) returning int
逆から読むと
func_pはint型を返す(引数がダブル型)関数のポインタ

atexit()のプロトタイプ宣言
int atexit(void(*func)(void));

同様にして
atexit is a function(func is a pointer to function(void) returning void)returning int.
atexitはint型を返す関数(fancはvoid型を返す関数(void)のポインタ)
因みにatexitはプログラムが正常終了したときに登録した関数を呼び出してもらう関数。

signal()のプロトタイプ宣言
void (*signal(int sig,void (*func)(int)))(int);

signal is function(sig is int,func is pointer to function(int)returning void) **returning** pointer to function(int) returning void

こうなるようなのですが私には何故signal is function() *returning*←となるのか理解できなかった。スミマセン