您的位置:首页 > 编程语言 > C语言/C++

《IOS_C语言》函数指针、函数回调、动态排序、函数返回值是函数指针

2015-09-01 21:11 651 查看
一:函数指针(函数地址跟数组名类似,指向函数的首地址)

1、函数指针的定义(没有固定的类型,只有某一类的函数指针)

格式:int maxValue(int a,int b);

int (*p)(int a,int b)=NULL;

p是变量,其他都是他的类型,参数是两个int型组成,返回值是一个int型,并且赋初值为NULL即是=0;

使用时,直接把函数名换成指针名

p=maxValue;

int m=p(3,6);//这里实际是=maxValue(3,6);

课上练习1:定义一个函数指针和使用:

(1)函数定义:

void printHello()

{

printf("Hello!");

}

(2)函数指针的使用:

void(*p)()=NULL;//先置空值

p=printHello;//令指针名=函数名

p();//相当于函数printHello()调用函数

二:函数回调

与函数的调用不一样,因为使用指针函数回调是动态的调用,而函数嵌套调用已经确定的,静态调用。(指指针作为参数)

格式:int getValue(int a,int b,int(*p)(int,int));

int value=getValue(3,5,maxValue);getValue执行过程中调用maxValue函数

课上练习(重点理解):定义两个函数,一个求最大值,一个求和,输入max或者sum,分别求3,5的最大值和和,提示定义一个函数指针,很据输入的内容指向不同函数,最后一次调用完成。

(1)函数定义:

int getmax(int a,int b)

{

return max=a>b?a:b;

}

int getsum(int a,int b)

{

return sum=a+b;

}

(2)main函数里面的指针函数的调用

int(*p)(int a,int b)=NULL;由于上面的连个函数的类型和形参以及返回值都一样,所以之定义一个指针函数就可以了。

char str[30]={0};//用于存放客户输入的需求

printf("请输入sum或者max\n");

scanf("%s",str);

if(strcmp(str,"sum")==0){//根据输入的不同使得函数指针名等于不同的函数名,从而实现执行不同的函数操作

p=getsum;

}else if(strcmp(str,"max")==0){

p=getmax;

}

int result=p(5,7);/调用函数,并且结果用一个整型的变量来装结果。

printf("%s",ressult);

//课上练习3:

//实现函数的动态调用

(1)函数定义

int getValue(int a,int b,int(*p)(int a,int b))

{

return p(a,b);//实际上getValue()函数就是根据指针函数所调用的函数而输出结果的

}

(2)函数指针的使用

int result=getValue(5,6,getmax)//实际上的意思p=getmax

printf("%d",result);

//课上练习4:写⼀一函数查找成绩90分以上的学员,使⽤用回调函数在姓名后加”⾼高富帅”。

(1)函数的定义以及结构体的定义

typedef struct stu

{

char name[30];

float score;

}Student;

//拼接函数

void addName(char*str1,const char*str2)

{

strcat(str1,str2);

printf("%s\n",str1);

}

//在数组中寻找满足条件的使用指针函数p调用拼接函数

void findScoreAddString(Student*stus,int count,void(*p)(char*str1,char*str2))

{

for(int i=0;i<count;i++){

if(stus[i]>90){

p(stus[i],"高富帅");

}

}

}

//打印学生信息函数

void print(Student *stus,int count)

{

for(int i=0;i<count;i++){

printf("%s,%.2f",stus[i].name,stus[i].score);

}

}

(2)main函数里面使用函数指针达到函数回调作用

Student stu1={"zhangsan",98};

Student stu2={"hahahhah",36};

Student stus[2]={stu1.stu2};

print(stus,2);

findScoreAddString(stus,2,addstring)或者

void(*p)(char*,const char*)=NULL;

p=addstring;

findScoreAddString(syus,2,p);

print(stus,2);

三:动态排序

以前学的是静态排序,把所有排序写好,根据客户的需求进行调用和排序,如淘宝商城根据不同的需求进行排序,使用函数指针进行指向。

typedef BOOL(*PFUN)(int ,int);//加了typedef(取别名,这里就表示PFUN就不仅仅是一个指针名,更是指返回值是bool型,形参是两个int型的函数指针,也表示这样的类型,即:BOOL(*PFUN)(int,int)这一串等价于PFUN类型,下次使用就不需要再次定义一大串BOOL(*PFUN)(int,int),只需要类型PFUN+变量名就可以了)

如://如:动态排序函数声明(下面直接声明p的类型是BOOL类型返回值,参数是两个形参)

// void sortArray(int * arr,int count,PFUN p);//PFUN p是核心

课上练习:根据客户的需求对学生信息进行排序,排序的办法有根据姓名升序、降序排序,根据成绩的升序、降序排序

首先定义一个结构体数组

typedef struct stu

{

char name[30];

float score;

}Student;

//按照姓名的升序排序

void compareByNameUp(Student stu1,Student stu2)

{

if(strcmp(stu1.name,stu2.name)>0){

return 1;表示满足if(1)的条件,在排序那里则会执行交换位置进行升序排序

}else{

return 0;

}

}

//按照姓名的降序排序

void compareByNameLow(Student stu1,Student stu2)

{

if(strcmp(stu1.name,stu2.name)<0){

return 1;表示满足if(1)的条件,在排序那里则会执行交换位置进行升序排序

}else{

return 0;

}

}

//按照成绩升序排序
void compareByScoreUp(Student stu1,Student stu2)

{

return stu1.score>stu2.score;

}

//按照成绩降序排序

void compareByScoreUp(Student stu1,Student stu2)

{

return stu1.score<stu2.score;

}

(3)定义函数指针(由于以上的返回都是一样的bool类型,形参都是结构体变量)

typedef BOOL(*p_fun)(Student stu1,Student stu2);//这一串的类型,可以直接用p_fun表示类型

(4)数组排序函数:

void sortArray(Student *stus,int count ,p_fun p)

{

for(int i=0;i<count-1;i++){

for(int j=0;j<count-1-i;j++){

if(p(stus[j],stus[j+1])){//根据传进来的不同函数指针,执行不同的函数

Student temp=stus[j];//交换的是学生结构体变量

stus[j]=stus[j+1];

stus[j+1]=temp;

}

}

}

}

(5)main函数里面调用以上函数

Student stu1={"zhangsan",90.0};

Student stu2={"lisi",68.8};

Student stu3={"lihahha",100};

Student stus[3]={stu1,stu2,stu3};

int count=3;

//函数调用,根据客户输入(用switch case)

int number=0;

printf("按照姓名升序请按1\n按照姓名降序请按2\n按照分数升序请按3\n按照分数降序请按4\n");

scanf("%d",&number);

p_fun p;

switch(number){

case 1:

p=compareByNameUp;

break;

case 2:

p=compareByNameLow;

break;

case 3:

p=compareByScoreUp;

break;

case 4:

p=compareByScoreLow;

break;

default:

printf("您输入错误,请输入1~4\n");

break;

}

//排序函数调用

sortArray(stus,count,p);//调用上面的动态排序函数,p再动态根据客户输入的选择而调用不同的函数

print(stus,count);//调用打印学生信息的函数

四:函数返回值是函数指针

//4、函数返回值是函数指针

//如:百度地图

// PFUN getFunctionByName(char*name);//返回的就是PFUN的函数指针类型的

//课上练习知识点4:通过字符串来获取函数功能

/*********通过字符串查找要执行对应的功能*********************/

(1)各种功能函数的定义

int max(int a,int b)

{

return a>b?a:b;

}

int sum(int a,int b)

{

return a+b;

}

int muli(int a,int b)

{

return a*b;

}

int sub(int a,int b)

{

return a-b;

}

(2)定义指针函数(上面的函数都是同类型的)

typedef int(*p_fun)(int ,int);//直接把这种类型定义成p_fun

(3)定义功能结构体,让输入的函数名name与函数名建立一一对应关系

typedef struct function

{

char name[30];

p_fun fun;//定义函数指针的变量名为fun

}Function;

//定义全局功能结构体数组(并且只能这么定义)

Function function[]={{"max",max},{"sum",sum},{"muli",muli},{"sub",sub}};

//使得函数名和输入的名字建立一一对应关系

//通过字符串获取对应的函数指针的函数,返回值是函数指针,因此定义返回值也是函数指针类型的

p_fun getFunctionByName(char*name)

{

for(int i=0;i<sizeof(function)/sizeof(Function),i++){//sizeof(function)计算整个数组所占用的字节数,sizeof(Function)计算一个结构体所占的字节,sizeof(function)/sizeof(Function)表示计算出有多少个功能数组

if(strcmp(function[i].name,name)==0){

return function[i].fun;

}

}

return 0;

}

(4)通过获取出来的函数,实现对应函数的功能

int getResult(int a,int b,p_fun fun)

{

if(fun==0){

return 0;

}else{

return fun(a,b);//调用对应的函数功能,并且返回对应处理后的值

}

}

(5)主函数里面

char name[30]={0};

printf("please input a name,sum或者max或者muli或者sub\n");

scanf("%s",name);

p_fun fun=getFunctionByName(name);//找函数名

int result=getResult(3,5, fun);//根据指针函数名找到结果

printf("result=%d\n",result);//返回结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: