-
- #include<stdio.h>
-
- typedef int (*FP_CALC)(int, int);
//此处typedef定义的是一个函数指针类型 FP_CALC, 该函数指针指向的函数要返回值是int型, 两个参数也是int 。 FP_CALC f1; f1=add;是可以的呀。 - //注意这里不是函数声明而是函数定义,它是一个地址,你可以直接输出add看看
- int add(int a, int b)
- {
-
return a + b; - }
- int sub(int a, int b)
- {
-
return a - b; - }
- int mul(int a, int b)
- {
-
return a * b; - }
- int div(int a, int b)
- {
-
return b? a/b : -1; - }
- //定义一个函数,参数为op,返回一个指针。该指针类型为 拥有两个int参数、
- //返回类型为int 的函数指针。它的作用是根据操作符返回相应函数的地址
- FP_CALC calc_func(char op)
- {
-
switch (op) -
{ -
case '+': return add;//返回函数的地址 -
case '-': return sub; -
case '*': return mul; -
case '/': return div; -
default: -
return NULL; -
} -
return NULL; - }
- //s_calc_func为函数,它的参数是 op,
- //返回值为一个拥有两个int参数、返回类型为int 的函数指针
- int (*s_calc_func(char op)) (int, int)
- {
-
return calc_func(op); - }
- //最终用户直接调用的函数,该函数接收两个int整数,和一个算术运算符,返回两数的运算结果
- int calc(int a, int b, char op)
- {
-
FP_CALC fp = calc_func(op); //根据预算符得到各种运算的函数的地址 -
int (*s_fp)(int, int) = s_calc_func(op);//用于测试 -
// ASSERT(fp == s_fp); // 可以断言这俩是相等的 -
if (fp) return fp(a, b);//根据上一步得到的函数的地址调用相应函数,并返回结果 -
else return -1; - }
-
- void main()
- {
-
int a = 100, b = 20; -
-
printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+')); -
printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-')); -
printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*')); -
printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/')); - }
以上讲的是函数指针,也可以这样用:
#include <stdio.h> void say_hello(const char *str) { printf("Hello %s\n", str); } int main(void) { void (*f)(const char *) = say_hello; f("Guys"); return 0; }
除了函数指针,普通函数也可以用typedef,如:
typedef int F (void);//定义函数类型F
之后可以这样声明:
F f,g;相当与声明
int f(void);
int g(void);
下面这个函数声明是错误的:
F h(void);
因为函数可以返回void
类型、标量类型、结构体、联合体,但不能返回函数类型,也不能返回数组类型。而下面这个函数声明是正确的:
F *e(void);
函数e
返回一个F *
类型的函数指针。如果给e
多套几层括号仍然表示同样的意思:
F *((e))(void);
但如果把*
号也套在括号里就不一样了:
int (*fp)(void);
这样声明了一个函数指针,而不是声明一个函数。fp
也可以这样声明:
F *fp;
顺便提下指针函数:
【指针函数】
一个函数不仅可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。
int *f(x,y);
其中x,y是形式参数,f是函数名,调用后返回一个指向整型数据的地址指针。f(x,y)是函数,其值是指针。
如:char *ch();表示的就是一个返回字符型指针的函数,请看下面的例题:
【例】将字符串1(str1)复制到字符串2(str2),并输出字符串2.
#include "stdio.h"
main()
{
}
char *ch(char *str1,char *str2)
{
}
通过分析可得
函数指针是一个指向函数的指针,而指针函数只是说明他是一个返回值为指针的函数,
函数指针可以用来指向一个函数。
回调函数
如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(Callback Function)。例如qsort(3)
和bsearch(3)
。
void func(void (*f)(void *), void *p);
调用者
调用者 | 实现者 |
---|---|
|
|