数组是有类型的,一样的,函数也有类型。函数的类型是由返回值类型,参数类型以及参数个数三者共同决定的。数组
type (parameter list)
C语言中,可使用typedef关键字对数组类型进行重命名,既然函数也是有类型的,那么一样可使用typedef为函数类型进行重命名。例如,ide
typedef int F (int, int); typedef void P (char, int); typedef float pf (float, float, int); typedef char pc (void);
int型的数据能够经过int 指针指向,float类型的数据可使用float 指针指向,数组类型能够经过数组指针指向,那么函数类型就能够经过函数指针指向。函数
函数指针,本质是指针,用于指向一个函数。前面讲过,一个函数,它的类型是由返回值类型,参数类型以及参数个数共同决定,所以,指针
int add(int, int); float minus(float, float); int (*pi) (int, int) = add; float (*pf) (float, float) = minus;
因为typedef关键字能够对函数类型重命名,所以,上面那种写法又能够简写为,code
typedef int PI (int int); typedef float PF (float, float); PI* pi = add; PF* pf = minus;
typedef int (FUNC) (int); int test(int i){ return i + i; } void func(){ printf("Call func()...\n"); } int main(){ FUNC* pt = test; void (*pf) () = &func; //void (*pf) () = func; pf(); (*pf)(); //func(); }
因为函数名就是函数入口地址,所以对函数名取地址,其实仍是函数入口地址自己,没有什么区别。所以,如下两种写法等价,事件
void (*pf) () = &func; 等价于 void (*pf) () = func;
一样的是,调用函数时的写法也是等价的,回调函数
pf(); 等价于 (*pf)(); 等价于 func();
回调函数是利用函数指针实现的一种回调机制。回调机制的基本原理:it
咱们在用餐时,根据喜爱不一样,会选择吃的食物也不一样。有的人喜欢吃米食,有的人喜欢吃面食...,那么根据饮食习惯的不一样,定义两种食物,class
int Rice(void){ printf("I like eatting rice...\n"); return 3; } int Noddle(void){ printf("I like eatting noddle...\n"); return 2; }
这个时候,小明和小红一块儿用餐,小明喜欢吃米食,小红喜欢吃面食。因而就有,test
typedef int (*FOOD) (void); void Eat(FOOD food){ printf("begin to eat...\n"); int result = food(); printf("I eat %d bowls...\n", result); printf("end...\n"); } int main(){ Eat(Rice); //小明吃米食 Eat(Noddle); //小红吃面食 return 0; }
以上的状况就是,Eat()做为调用者,不知道本身调用的具体内容是什么,多是Rice(),多是Noddle(),也多是其余;而被调函数Rice(),Noddle()也不知道本身什么时候会被调用,也可能不会被调用,视状况而定。而且,调用者是经过函数指针完成对被调函数的调用,且调用者与被调函数彻底互不依存。所以,彻底符合回调机制的原理。