ISD実習E 2009年6月29日 LISPシステム入門 (第5回) 関数ポインタ eval システム関数
eval関数(V0.9) スタック stack[1000] V0.9では、関数呼び出しのとき 関数に与えられた引数を評価した値を スタックに入れて呼び出す。 呼び出しが終了すると、スタックはもとに 戻される。 (+ 2 3) のとき、2,3 をstackに入れてその処理関数である s_plus を呼んでいる。(eval_slambda ) 関数s_plusは、シンボル + の値(シンボルのCDR) に1個のセルとして、そのCARが関数ポインタ タグはSLAMBDAとして作られている。
関数ポインタ 関数ポインタの宣言 int (*func)(int x,int y); は、その関数の開始アドレスをその 値として持っている。 C言語では、関数の名前(main,...) は、その関数の開始アドレスをその 値として持っている。 これを使って、関数ポインタをある場所に 保存したり、その値を用いて関数呼び出しを 行ったりすることができる。 関数ポインタの宣言 int (*func)(int x,int y);
例 int add2(int x, int y){ return x ,y; } main(){ int (*func)(int x,int y); func=add2; printf(“%d¥n”,(*func)(4 ,5));
関数ポインタの配列 int (*func[2])()={add2,mul2}; この呼び出しは、 (*func[0])(3,4); のように行う。確認せよ。
関数ポインタのcast 一般にcast変換は、 (型名) 変数; である。 関数ポインタのcast変換は、宣言の形 から変数部分を取り除いたものを使う。 func=(int (* )())x; eval.c の関数eval_slambdaはこれを 使っている。
やってみよう eval.c を変更して * - / assq write read eval などを、追加してください。