首先,我们先要明确一点,函数指针是一个指针,只不过这个指针指向的对象有些特殊,是一个函数。指针函数是一个函数,只不过函数的返回值是一个指针。
一、指针函数,指针函数的一般定义格式是:
类型* 函数名(形参列表)
{
语句块;
return 返回值;
}
举个例子如下:
#include <stdio.h>
#include <string.h>
char* fun(char p[],int n)
{
char *buf;
buf = p;
return buf;
}
int main()
{
char str[]="pointer";
printf("%s",fun(str,strlen(str)));
return 0;
}
编译及运行结果如下
二、函数指针
1.函数指针的定义格式:
返回类型 (*函数指针名)(形参类型列表);//注:可以没有形参类型列表,但要有 () 表示形参类型及个数在赋值时决定
例如:int (*fun)(int); 这就定义了一个指向返回值为int型,形参为int型的函数的函数指针 fun。
2.函数指针的赋值:
有这么一个和fun指针匹配的函数fun1,那么它的赋值为:fun = fun1;
int fun1(int n)
{
printf("%d\n",n);
return 0;
}
3.函数指针的一个应用是回调函数,下面我们定义俩个不同的.cpp文件,实现一个回调函数
第一个文件fs.cpp
/*NULL的头文件*/
#include <stddef.h>
extern int fun1(int n);
int(*g_funp)(int)=NULL;
int fun(int(*funp)(int n))
{
fun1(100);
g_funp = funp;
return 0;
}
第二个文件test.cpp
#include <stdio.h>
#include <string.h>
/*回调函数*/
extern int fun(int (*funp)(int n));
int fun1(int n)
{
printf("%d\n",n);
return 0;
}
int main()
{
fun(fun1);
return 0;
}
编译及运行结果如下:
程序分析:
main函数调用fun函数,并传递一个函数指针fun1,在fun函数中又去回调fun1函数,其中在fs.cpp文件中又定义了一个函数指针g_funp,并在fun中将传过来的参数赋值给它,目的是以后能在fs.cpp中其他函数中调用这个fun1(当然这个是在fun1定义成static时的一种处理,fun1如果没有定义成static时直接使用extern声明调用即可),一般函数指针在linux中的写法常是被封装成结构体的一个成员,然后在传参的时候把整个结构体传过去,接着再去处理函数指针这个成员。
4.函数指针的另一个应用,函数指针数组
对于有多个函数调用时,正常我们会通过输入的编号结合switch case去调用对应的函数,那么当函数个数十分庞大时就 使用switch case的效率就十分低了,为此我们引入函数指针数组
举个例子如下:
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int dec(int a,int b)
{
return a-b;
}
int seq(int a)
{
return a*a;
}
int main()
{
/*因为函数的参数个数既有一个的也有俩个的所以定义成()这种形式*/
int (*funparry[3])()={add,dec,seq};
int i=0,data1=0,data2=0,ret;
while(1)
{
printf("0. add\n");
printf("1. dec\n");
printf("2. seq\n");
printf("select number\n");
scanf("%d",&i);
if(i==2)
{
printf("input data1\n");
scanf("%d",&data1);
ret = funparry[i](data1);
}
else
{
printf("input data1 and data2\n");
scanf("%d %d",&data1,&data2);
ret = funparry[i](data1,data2);
}
printf("result is %d\n",ret);
}
return 0;
}
执行结果如下: