学习自狄泰软件学院唐佐林老师C语言课程,文章中图片取自老师的PPT,仅用于个人笔记。
实验0 :直接定义函数指针类型
实验1 :函数指针的使用
实验2 :通过函数指针直接跳转到某个固定地址开始执行
实验3:回调函数使用
函数指针是实现函数回调的关键技术!!!
可以直接定义函数指针类型:
#include <stdio.h>
int func(int x)
{
return x;
}
//或者 typedef int(PFUNC)(int a); PFUNC* p
typedef int(*PFUNC)(int a);
int main(int argc, char *argv[])
{
int c = 0;
PFUNC p = func;
c = p(1);
printf("c = %d\n", c);
return 0;
}
函数的入口地址 就是函数名,加不加 & 并没有影响
实验1 :函数指针的使用
#include <stdio.h>
// 定义新的函数类型
typedef int(FUNC)(int);
int test(int i)
{
return i * i;
}
void f()
{
printf("Call f()...\n");
}
int main()
{
/*
函数的入口地址 就是函数名,加不加 & 并没有影响
*/
//定义函数指针并初始化,函数名代表函数入口地址
FUNC* pt = test;
//直接定义函数指针,返回值为void ,无参数。 并用f()入口地址初始化
void(*pf)() = &f;
//打印函数入口地址
printf("pf = %p\n", pf);
printf("f = %p\n", f);
printf("&f = %p\n", &f);
//直接用函数指针调用函数 此时pf是函数指针 函数指针中保存的就是函数入口地址
pf();
//老式的写法 加* 去函数指针所保存的地址 等价于 pf();
(*pf)();
printf("Function pointer call: %d\n", pt(2));
return 0;
}
mhr@ubuntu:~/work/C$ gcc 36-1.c
mhr@ubuntu:~/work/C$
mhr@ubuntu:~/work/C$
mhr@ubuntu:~/work/C$ ./a.out
pf = 0x400576
f = 0x400576
&f = 0x400576
Call f()...
Call f()...
Function pointer call: 4
mhr@ubuntu:~/work/C$
实验2:通过函数指针直接跳转到某个固定地址开始执行
根据实验1的结果 我们修改代码,直接给函数指针赋值 函数的入口地址
#include <stdio.h>
// 定义新的函数类型
typedef int(FUNC)(int);
int test(int i)
{
return i * i;
}
void f()
{
printf("Call f()...\n");
}
int main()
{
/*
函数的入口地址 就是函数名,加不加 & 并没有影响
*/
//定义函数指针并初始化,函数名代表函数入口地址
FUNC* pt = test;
//直接定义函数指针,返回值为void ,无参数。直接用入口地址初始化
void(*pf)() = 0x400576;
//打印函数入口地址
printf("pf = %p\n", pf);
printf("f = %p\n", f);
printf("&f = %p\n", &f);
//直接用函数指针调用函数 此时pf是函数指针 函数指针中保存的就是函数入口地址
pf();
//老式的写法 加* 去函数指针所保存的地址 等价于 pf();
(*pf)();
printf("Function pointer call: %d\n", pt(2));
return 0;
}
mhr@ubuntu:~/work/C$ gcc 36-1.c
mhr@ubuntu:~/work/C$
mhr@ubuntu:~/work/C$
mhr@ubuntu:~/work/C$ ./a.out
pf = 0x400576
f = 0x400576
&f = 0x400576
Call f()...
Call f()...
Function pointer call: 4
mhr@ubuntu:~/work/C$
通过函数指针可以直接跳转到某个固定地址开始执行
实验3:回调函数使用
该实验,如果不使用回调机制,那么在每次调用 fight()的时候 都要在里面手动的指定调用的目标,这样如何进行游戏啊,每次的攻击方式都是固定的。
result = knife(arg);
result = sword(arg);
result = gun(arg);
通过函数指针实现了回调,通过回调的方式来实现了动态的选择攻击方式!!
这里直接用函数名(即函数的入口地址)初始化函数指针。
.
#include <stdio.h>
//定义函数指针
typedef int(*Weapon)(int);
/*
Weapon wp : 函数指针
*/
void fight(Weapon wp, int arg)
{
int result = 0;
printf("Fight boss!\n");
result = wp(arg);
printf("Boss loss: %d\n", result);
}
int knife(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Knife attack: %d\n", 1);
ret++;
}
return ret;
}
int sword(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Sword attack: %d\n", 5);
ret += 5;
}
return ret;
}
int gun(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Gun attack: %d\n", 10);
ret += 10;
}
return ret;
}
int main()
{
//通过函数名来直接传递函数入口地址,这里直接用函数名(即函数的入口地址)初始化函数指针。
fight(knife, 3);
fight(sword, 4);
fight(gun, 5);
return 0;
}