第14回

関数へのポインタ

00/11/14 誤字脱字を訂正した
00/06/29 サンプルプログラムのインデントを改善した
98/11/06 IE4.xに対応させた
98/04/29メールアドレス訂正

int型変数aと、int型のポインタbがあったとします。その状況下におけるb=&aは、ご存知の通りポインタbが変数aのアドレスを指し示すという意味です(忘れた方はこちら)。それと同様に、ポインタは変数だけではなく、関数のアドレスを指し示すことも可能です。
関数へのポインタは以下のように宣言します。
型 (* ポインタ名)();

例えば
int f(int x);
とプロトタイプ宣言されているf関数のアドレスを、関数へのポインタaを使って指し示す場合は、
int (* a)();
と宣言した上で、
a=f;         /* ポインタaは、f関数のアドレスを指し示す  */
とします。
ここで注意してほしいのは、関数名そのものは、配列名の時と同じように、その先頭アドレスを指し示すものだということです。その為、関数名の前に単項演算子&はいりません。
これで、
a(10);
とした場合、それは、f(10)と同じ意味になるのです。
あ、でもこの書き方は、処理系によってはエラーになるかもしれません。その場合は、ええと、
(*a)(10);
と書けばいいでしょう(こっちの書き方を覚えた方がいいかも)。
前回のプログラムで、関数へのポインタを使う(ナンセンスだけど)と、以下のようになります。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int sakebi(char *c,int a,int b);

main(){
    int(* p)();

    p=sakebi;       /*   ポインタpは、sakebi関数のアドレスを指し示す      */
    srand((unsigned int)time(NULL));

    printf("これは、お前に踏み潰されたスライムの痛みだッ!!\n");
    p("ラスボス(首)",3,10);

    printf("これは、ひなたぼっこ中に不意打ちを喰らったゴブリンの怒りだッ!\n");
    p("ラスボス(腹)",6,100);

    printf("ええと、余計なお世話の回復呪文で浄化してしまったスケルトンの分だぁッ!\n");
    p("ラスボス(右足すね)",9,0);

    printf("そしてこれは、全てを失った俺の怒りだッ!!\n");
    p("カウンターッ!!\n貴方",0,10000);
    printf("ぐふッ。\n");
}
int sakebi(char *c,int a,int b){
int i;

    if(b!=0)b=rand()%b+1;
    if(a==0)printf("いい加減にしろ。>いーざ\n");
    else{
        printf("うぎゃ");
        for(i=0;i<a;i++)printf("ぁ"); 
        printf("ッ!!\n");
    }
    printf("%sは、%dポイントのダメージ!!\n",c,b);
    return b;
}
で、この書き方が駄目な時は(mainのみ)、
main(){
    int(* p)();

    p=sakebi;       /*   ポインタpは、sakebi関数のアドレスを指し示す      */
    srand((unsigned int)time(NULL));

    printf("これは、お前に踏み潰されたスライムの痛みだッ!!\n");
    (*p)("ラスボス(首)",3,10);

    printf("これは、ひなたぼっこ中に不意打ちを喰らったゴブリンの怒りだッ!\n");
    (*p)("ラスボス(腹)",6,100);

    printf("ええと、余計なお世話の回復呪文で浄化してしまったスケルトンの分だぁッ!\n");
    (*p)("ラスボス(右足すね)",9,0);

    printf("そしてこれは、全てを失った俺の怒りだッ!!\n");
    (*p)("カウンターッ!!\n貴方",0,10000);
    printf("ぐふッ。\n");
}
つづく。

[メニュー][第13回][第15回]

いーざ
email:CQP00202@nifty.ne.jp