1.関数ポインタ
最初にコードの一部を見てください
#include<stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
}
出力は2つのアドレスで、これら2つのアドレスはテスト関数のアドレスです。次に、関数のアドレスを保存します。どのように保存しますか?
まず、アドレスを格納できるようにするには、関数へのポインター変数、つまり関数ポインターが必要です。
void (*fun1)();
fun1は最初にポインターと結合され、fun1がポインターであり、ポインターが指す関数にパラメーターがなく、戻り値の型がvoidであることを示します。
2つの興味深いコードを見てみましょう
(*(void(*)())0)()
0をvoid(*)()型の関数ポインタに強制的に変換します。0は関数のアドレスです。逆参照後、アドレス0の関数が呼び出されます。
void (*signal(int ,void(*)(int)))(int)
まず、signalは関数宣言です。関数には、整数と関数ポインタ型の2つのパラメータがあります
。関数の戻り値の型は関数名とパラメータを削除することで、残りは戻り値の型です。関数の戻り値型も関数ポインタ型です。
このコードは少し複雑なので、単純化できます。
typedef void(* pfun_t)(int);
pfun_t signal(int ,pfun_t);
関数ポインタの使用
#include<stdio.h>
int add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int(*pa)(int, int) = add;
printf("%d\n", pa(2, 3));
printf("%d\n", (*pa)(2, 3));
}
2.関数ポインタ配列
int * arr [10]などのポインタ配列についてはすでに検討しました。
関数のアドレスを配列に格納する場合、この配列は関数ポインターの配列と呼ばれ、次のように定義されます。
int(*pa[10])(int ,int);
Paは[]と組み合わされ、paが配列であることを示します。配列の内容は何ですか。タイプint(*)(int、int)の関数ポインタです
考え:
char*my_strcpy(char*dest,const char*src);
1.my_strcpyを指すことができる関数ポインタを
記述します。2。4つのmy_strcpy関数のアドレスを格納できる関数ポインタ配列を記述します。
char*(*p)(char* ,const char*);
char*(*p[4])(char* ,const char*);
関数ポインタ配列目的:転送テーブル
例:計算機
#include<stdio.h>
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int, int) = {
0,add,sub,mul,div };
while (input)
{
printf("*******************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf("*******************************\n");
printf("请选择:");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
printf("请输入操作数:");
scanf("%d %d", &x, &y);
ret = p[input](x, y);
}
else
printf("输入有误\n");
printf("ret=%d\n", ret);
}
}
つづく...