函数类型
C语言中的函数有自己特定的类型
函数的类型由
返回值、参数类型和
参数个数(包括出现顺序)共同决定
例:int add(int i, intj)的类型为int(int, int)
C语言中
通过typedef为函数类型 重命名
typedef type
name(parameter list)
例:
typedef int f(int, int);
typedef void p(int);
函数指针
函数指针用于
指向一个函数
函数名是执行函数体的入口地址
可通过函数类型定义函数指针:
typedef type FuncType(parameter list)
FuncType* pointer;
也可以直接定义: type (*pointer)(parameter list);
. pointer为函数指针变量名
. type为指向函数的返回值类型
. parameter list为指向函数的参数类型列表
例:
#include <stdio.h>
typedef int(FUNC)(int);//定义一个函数类型FUNC
int test(int i)//test函数是FUNC类型的
{
return i * i;
}
void f()
{
printf("Call f()...\n");
}
int main()
{
FUNC* pt = test;//用函数类型FUNC定义了一个指针pt指向函数test
//函数名就代表了一个地址,把函数名直接赋值给指针;用&作用于函数名和不用没有任何区别
void(*pf)() = &f;//用偷懒的方式定义了一个函数指针pf,指向函数f;
pf();//pf保存了一个函数地址,且这个函数没有参数,即等价于f()
(*pf)();//老方法,功能与 pf();一致,通过*打开防盗门,在函数指针pf得到函数f的地址
printf("Function pointer call: %d\n", pt(2));
}
result:
Call f()...
Call f()...
Function pointer call: 4
回调函数
回调函数是利用函数指针实现的一种调用机制
回调机制原理
.
调用者(遇到事情,但不会处理事情) 不知道具体事件发生的时候需要调用的具体函数
.
被调函数(会处理事情,但不会遇到事情) 不知道何时被调用,只知道被调用后需要完成的任务
. 当具体事件发生时,调用者通过函数指针调用具体函数
回调机制要将调用者和被调函数分开,两者互不依赖(有利于模块化编程)
回调函数的使用示例
#include <stdio.h>
typedef int(*FUNCTION)(int);//定义了一个函数指针
int g(int n, FUNCTION f)//李逍遥(调用者),f是函数指针
{
int i = 0;
int ret = 0;
for(i=1; i<=n; i++)
{
ret += i*f(i);
}
return ret;
}
int f1(int x)//锦囊1
{
return x + 1;
}
int f2(int x)//锦囊2
{
return 2*x - 1;
}
int f3(int x)//锦囊3
{
return -x;
}
int main()
{
printf("x * f1(x): %d\n", g(3, f1));//把f1作为参数注册给g,g就可以具体知道f是什么,就可以工作了
printf("x * f2(x): %d\n", g(3, f2));
printf("x * f3(x): %d\n", g(3, f3));
}
result:
x * f1(x): 20
x * f2(x): 22
x * f3(x): -14
指针阅读技巧解析
右左法则
1. 从
最里层 的圆
括号中 未定义的
标示符看起
2. 首先往右看,再往左看
3.
当遇到 圆括号 或者
方括号 时可以
确定部分类型,
并调转方向
4. 重复2,3步骤,直到阅读结束
#include <stdio.h>
int main()
{
int (*p2)(int*, int (*f)(int*));
//(*p2)是指针,去掉p2,
//往右看(int*, int (*f)(int*)),是个函数,这个函数参数第一个是int*,
//第二个参数是函数指针,参数为int*,类型为int
//,往左看,类型是int,
int (*p3[5])(int*);
//p3未定义,往右看,遇到[,确定p3是一个数组,有5个元素,即p3[5]
//拿出来已经确定的,变成int (*)(int*);右左法则:继续往左看是),往右看是(,可以确定p3的这五个元素是指针
//拿出来已经确定的,变成int (int*);往右看,遇到(,p3是函数指针
//p3是一个包含五个元素的数组,每个元素都包含一个指针,函数指针指向的函数类型是int (int*)
int (*(*p4)[5])(int*);
//p4是一个数组指针,指向一个数组,数组有五个元素,
//每一个元素还是一个指针,每一个指针指向一个函数,函数类型是int (int*)
int (*(*p5)(int*))[5];
}