C言語関係掲示板

過去ログ

No.590.int func(int (*fp)(int)) と int func(int fp(int))

[戻る] [ホームページ]
No.5585

関数へのポインタ
投稿者---シスコ(2003/03/14 23:17:43)


こんにちわ。シスコです。

現在、関数へのポインタの勉強をしているのですが、
なぜ,△陵僂暴颪韻襪里がわかりません。

どなたか、わかりやすく教えていただけないでしょうか?

======
int func(int (*fp)(int))
{
        return((*fp)(555));
}

======
int func(int fp(int))
{
        reutnr(fp(555));
}


よろしくお願いします。

No.5588

Re:関数へのポインタ
投稿者---aki(2003/03/15 17:05:57)


仮引数宣言においては、関数の宣言は関数へのポインタの宣言に調整され
ます。これは、同じく仮引数宣言で、配列の宣言がポインタの宣言に調整
されるのと同じような理由によるものです。まず配列の場合について説明
します。下の関数 g の仮引数宣言 char x[] は char *x に調整されます。

void g(char x[])	/* (A) 配列の宣言をポインタの宣言に調整 */
{
    x[0] = 1;
}

void f(void)
{
    char x[10];
    g(x);         /* (B) 配列名 x はポインタに変換される */
}

(A)の調整、(B)の変換は、配列の参照渡しを実現するからくりを提供するも
のだと考えることができます。実際には関数にはポインタが渡されているの
ですが、見かけでは、配列が渡されているように見えます。このような「み
せかけ」を嫌うなら、仮引数宣言で素直にポインタを宣言できます。

関数の場合も同様です。下の関数 g の仮引数宣言 void x(void) は 
void (*x)(void) に調整されます。

void g(void x(void)) /* (A') 関数の宣言を関数へのポインタの宣言に調整 */
{
    x();             /* もちろん (*x)() でもよい */
}

void f(void)
{
    void func(void);
    g(func);         /* (B') 関数指示子 func はポインタに変換される */
}

実引数の配列名がポインタに変換されるのと同じように、実引数の関数指示
子(例えば関数名)は関数へのポインタに変換されてから関数に渡されます。
受け取り側では仮引数の関数宣言をポインタ宣言に調整してこのポインタを
受け取ります。(A')(B')がセットになって働き、関数に関数を渡しているか
のような「みせかけ」を提供します。配列の場合と同様に、このような「み
せかけ」を嫌うなら、やはり仮引数宣言で素直にポインタを宣言できます。


No.5590

Re:関数へのポインタ
投稿者---シスコ(2003/03/16 20:52:54)


akiさん。こんばんは。
ご返信ありがとうございます。

なるほど、配列の時と同じように
「みせかけ」なのですね。

安心しました。ポインタでは、何度も
挫折しているため、本当に助かります。