<STEP1>
この単元では、関数のポインタを配列に保存して、アクセスする方法を学習します。
まずは、下のコードを入力してください。
#include <stdio.h>
void f1(int);
void f2(int);
void f3(int);
int main(){
void(*pf[3])(int);
pf[0] = f1;
pf[1] = f2;
pf[2] = f3;
(*pf[0])(2);
(*pf[1])(5);
(*pf[2])(8);
return 0;
}
void f1(int n){
printf("%d * %d = %d\n", n, n+2, n*(n+2));
}
void f2(int n){
printf("%d + %d + %d = %d\n", n, n+1, n+2, n+(n+1)+(n+2));
}
void f3(int n){
printf("仮引数は、%dです\n",n);
}
【解説】
void f1(int);
でプロトタイプ宣言される関数のポインタは、
void (*pf)(int);
で宣言して、
pf = f1;
のようにアドレスを代入していましたね。※関数名はアドレスを意味します。
思い出せない方は、https://ameblo.jp/neugate/entry-12375817631.htmlをみて復習してください。
したがって、関数のアドレスを入れる配列を宣言するためには、
void (*pf[3])(int);
のように宣言すればいいですね。
関数のポインタ宣言と関数のポインタ配列宣言の方法を比較して見ると、理解が進むと思います。
void (*pf)(int); ⇔ void (*pf[3])(int);
また、
void(*pf[3])(int);
pf[0] = f1;
pf[1] = f2;
pf[2] = f3;
の部分の書き方ですが、このように宣言〜代入の書き方ではなく、
void(*pf[3])(int) = {f1, f2, f3};
のように初期化する方法もあります。
※※※ここで注意!!
あくまでも、配列ですので、同じ型の関数ポインタしか配列としてまとめて表すことができません。
今回はプロトタイプ宣言をみてわかる通り、
void f1(int);
void f2(int);
void f3(int);
このように、戻り値も引数も同じ型の関数だったため、配列でまとめることができたわけです。
<STEP2>
typedefで、ポインタの名前をリネームすることもできます。
その方が、扱いやすくなります。
<STEP1>をtypedefでFに書き換えてみると…
#include <stdio.h>
void f1(int);
void f2(int);
void f3(int);
typedef void(*F)(int);
int main(){
F pf[3] = {f1, f2, f3};
(*pf[0])(2);
(*pf[1])(5);
(*pf[2])(8);
return 0;
}
void f1(int n){
printf("%d * %d = %d\n", n, n+2, n*(n+2));
}
void f2(int n){
printf("%d + %d + %d = %d\n", n, n+1, n+2, n+(n+1)+(n+2));
}
void f3(int n){
printf("仮引数は、%dです\n",n);
}
どうでしょうか?前よりみやすくなりませんか?
F型の配列pf[3]を初期化しています。
<STEP3>
テキストP.34の例題を入力して、実行してみてください。
<STEP4>
問題メモ
void f1(int,int); // ex) 3+5=8を表示
void f2(int,int); // ex) 7-3=4
void f3(int,int); // ex) 3*5=15
void f4(int,int); // ex) 18/3=6
void (*pf[4])(int,int) = {f1, f2, f3, f4};
int n2 = 5;
(*pf[0])(n1,n2);
(*pf[1])(5,2);
(*pf[2])(3,5);
(*pf[1])(36,2);
}
printf("%d + %d = %d\n", x, y, x+y);
}
void f2(int x, int y){
printf("%d - %d = %d\n", x, y, x-y);
}
void f3(int x, int y){
printf("%d * %d = %d\n", x, y, x*y);
}
void f4(int x, int y){
printf("%d / %d = %d\n", x, y, x/y);
}