指针——C的灵魂
一、函数指针认知
1.定义函数地址:
如果在程序中定义了一个函数,在编译时,系统会为函数分配一段存储空间,这段存储空间的起始地址(又称入口地址)叫做函数指针。既然数组名就是地址,那么函数名就是地址。
2.如何定义一个函数指针变量:
如何定义一个函数指针变量呢?其实和普通指针变量一样,普通指针变量是这样定义的:
int a;
int *p;
char b;
char *p2;
函数指针变量是这样定义的:
int getData(int a,int b);
int (*p)(int a,int b);
3.使用函数指针变量:
使用变量有两种方式,直接访问(变量名)和间接访问(地址即变量指针),那么函数调用也一样,即直接访问(函数名)和间接访问(函数指针)。下面我们看两种函数的两种方式调用:
无参函数调用:
#include<stdio.h>
void printWelcome()
{
puts("程序启动,欢迎使用!\n");
}
int main()
{
void (*p)(); //定义一个函数指针
p = printWelcome; //函数指针指向函数
printWelcome(); //函数名调用
(*p)(); //函数指针调用
return 0;
}
运行结果:
有参函数调用:
#include<stdio.h>
int incData(int data)
{
return ++data;
}
int main()
{
int (*p)(); //定义一个函数指针
p = incData; //函数指针指向函数
printf("函数名调用结果:%d\n",incData(10)); //函数名调用
printf("函数指针调用结果:%d\n",(*p)(10)); //函数指针调用
return 0;
}
运行结果:
二、函数指针应用:回调函数
函数指针的好用之处就在于可以根据程序运行的不同情况,调用不同的函数,这就类似与java中的接口。这种函数也叫回调函数。在学习Linux系统编程线程部分和C++QT的信号与槽相关部分的时候都有类似的写法。以下是对回调函数做一个实际应用。
题目要求:输入一个数字,当数字为1的时候求两数最大值,当数字为2的时候,求两数最小值,当数字为3的时候,求两数之和。
#include<stdio.h>
#include<stdlib.h>
int getMax(int data1, int data2)
{
return data1>data2 ? data1:data2;
}
int getMin(int data1, int data2)
{
return data1<data2 ? data1:data2;
}
int getSum(int data1, int data2)
{
return data1+data2;
}
int dataHandler(int data1, int data2, int (*pfunc)(int , int ))
{
int ret;
ret = (*pfunc)(data1, data2);
return ret;
}
int main()
{
int a = 10;
int b = 20;
int ret;
int cmd;
int (*pfunc)(int , int );
printf("请输入一个数字:1(求两数最大值),2(求两数最小值),3(求两数之和)\n");
scanf("%d",&cmd);
switch(cmd){
case 1:
pfunc = getMax;
break;
case 2:
pfunc = getMin;
break;
case 3:
pfunc = getSum;
break;
default:
printf("输入错误!");
exit(-1);
break;
}
ret = dataHandler(a, b, pfunc);
printf("ret = %d\n",ret);
return 0;
}
运行结果: