函数回调
#import <Foundation/Foundation.h>
typedef struct{
char name[20];
char sex;
int age;
int score;
}Student;
void printfStudent(Student *p,int count){
for(int i=0;i<count;i++){
printf("%s,%c,%d,%d\n",p[i].name,p[i].sex,p[i].age,p[i].score);
}
}
//函数回调第一步:声明关键点的函数
typedef BOOL (*PFUN)(Student s1,Student s2);
//函数回调第二步1:实现函数1
BOOL bijiaoAge(Student s1,Student s2);
BOOL bijiaoAge(Student s1,Student s2){
return s1.age>s2.age;
}
BOOL bijiaoScore(Student s1,Student s2);
BOOL bijiaoScore(Student s1,Student s2){
return s1.score>s2.score;
}
BOOL bijiaoName(Student s1,Student s2);
BOOL bijiaoName(Student s1,Student s2){
return strcmp(s1.name, s2.name)>0 ? YES : NO ;
}
//函数回调第二步2:实现函数2
void paixu(Student *p,int count,PFUN st );
void paixu(Student *p,int count,PFUN st ){
//冒泡排序,从小到大排列。
for(int i=0;i<count-1;i++){
for(int j=0;j<count-1-i;j++){
if (st(p[j], p[j+1]))
{
//结构体类型可以整体赋值。
Student temp1=p[j];
p[j]=p[j+1];
p[j+1]=temp1;
}
}
}
}
int main(int argc, const char * argv[]) {
Student stus[3]={
{"zhangsan",'m',23,89},
{"lisi",'f',21,95},
{"wangwu",'m',25,92}
};
//这里传的两个参数,第一个参数不要用&stus,要用stus.数组做指针的参数
printfStudent(stus, sizeof(stus)/sizeof(stus[0]));
printf("=====================\n");
//函数回调第三步:函数回调
paixu(stus, sizeof(stus)/sizeof(stus[0]),bijiaoName);
printfStudent(stus, sizeof(stus)/sizeof(stus[0]));
return 0;
}
//函数指针数组
/*
int (*p[3])(int,int)={0};
可改为:
typedef int (*PFUN)(int,int);
PFUN p[3]={0};
p[0] = maxValue;
p[1] = sum;
*/
//返回值是函数指针
/*
int (*functionName(int a))(int,int);
可改为:
typedef int (*PFUN)(int,int);
PFUN functionName(int a);
*/
//动态调用
/*
动态调用是系统普遍支持的技术
要实现动态调用需要一个对应表
例如:使用函数名的字符串调用函数
函数名 函数指针
"max" "maxValue"
"min" "minValue"
"avg" "avgValue"
第一步定义一个结构体,里面放表对应关系的字段。
typedef struct nameFunctionPair{
char name[30];
PFUN function;
}NameFunctionPair;
第二步用结构体数组定义一个表的对应关系。
NameFunctionPair nfs[3]={
{"max",maxValue},{"min",minValue},{"avg",avgValue}
};
void
第三步动态调用
PFUN getFunctionWithName(char *name);
PFUN getFunctionWithName(char *name){
for(int i=0;i<3;i++){
if(strcmp(nfs[i].name,name)==0){
return nfs[i].function;
}
}
return maxValue; //返回一个默认值,以防找不到而出错。
}
int getValue2(int x,int y,char *functionName);
int getValue2(int x,int y,char *functionName){
PFUN p=getFunctionWithName(functionName);
return p(x,y);
}
主函数中调用: getValue2(10,20,"sum");
*/
举例1
#import <Foundation/Foundation.h>
//声明和实现运算函数
int sumValue(int x,int y);
int sumValue(int x,int y){
return x+y;
}
int avgValue(int x,int y);
int avgValue(int x,int y){
return (x+y)/2;
}
int maxValue(int x,int y);
int maxValue(int x,int y){
return (x>y)?x:y;
}
//关键点1:定义一个“PFUN”作为变量的函数指针类型
typedef int (*PFUN)(int,int);
//关键点2:定义结构体,并把表的对应关系用结构体数组形式列举出来
typedef struct nameFunctionPair{
char name[30];
PFUN function;
}NameFunctionPair;
NameFunctionPair nfs[3]={
{"sum",sumValue},
{"avg",avgValue},
{"max",maxValue}
};
//关键点3:声明和实现一个返回值为函数指针类型的函数(获取函数名)。
//注意:设置一个默认返回值,否则程序运行若找不到函数名会出错
PFUN getFunctionWithName(char *name);
PFUN getFunctionWithName(char *name){
for(int i=0;i<3;i++){
if(strcmp(nfs[i].name, name)==0)
return nfs[i].function;
}
return maxValue;
}
//关键点4:定义被调用函数,供调用函数调用(被调用函数)。
int getValue2(int x,int y,char *functionName);
int getValue2(int x,int y,char *functionName){
PFUN p=getFunctionWithName(functionName);
return p(x,y);
}
int main(int argc, const char * argv[]) {
printf("%d",getValue2(50, 20, "sum"));
printf("\n");
// return 0;
}
举例2:
/*
动态调用作业:
动态函数调用实现下列操作,输入2个数以及操作符计算结果。
@求最大公约数,$求最小公倍数,-求差,+求和 等等
*/
#import <Foundation/Foundation.h>
#define N 4
//求最大公约数函数:
int maxCommonDivisors(int x,int y);
int maxCommonDivisors(int x,int y){
int temp=(x<y?x:y),max=1;
for(int i=1;i<=temp;i++){
if((x%i==0)&&(y%i==0))
max=i;
}
return max;
}
//求最小公倍数函数:
int minCommonMultiple(int x,int y);
int minCommonMultiple(int x,int y){
int temp=maxCommonDivisors(x,y);
return x*y/temp;
}
//求差函数
int minusValue(int x,int y);
int minusValue(int x,int y){
return x-y;
}
//求和函数
int sumValue(int x,int y);
int sumValue(int x,int y){
return x+y;
}
//定义一个函数指针类型
typedef int (*PFUN)(int,int);
//定义一个结构体存放对应关系表
typedef struct corresponding{
char name[30];
PFUN founction;
}Corresponding;
Corresponding cp[N]={
{"@",maxCommonDivisors},
{"$",minCommonMultiple},
{"-",minusValue},
{"+",sumValue}
};
//声明和实现一个函数,根据字符串获取函数名,返回值为函数指针类型。
PFUN getFunctionWithName(char *name);
PFUN getFunctionWithName(char *name){
for(int i=0;i<N;i++){
if(strcmp(cp[i].name,name)==0)
return cp[i].founction;
}
return maxCommonDivisors;//默认调用最大公约数
}
//声明和实现调用函数
int getValue(int x,int y,char *functionname);
int getValue(int x,int y,char *functionname){
PFUN p=getFunctionWithName(functionname);
return p(x,y);
}
int main(int argc, const char * argv[]) {
// printf("最大公约数为:%d\n",maxCommonDivisors(18,9));
// printf("最小公倍数为:%d\n",minCommonMultiple(18,27));
int x,y;
char c;
printf("请输入两个整数用空格隔开:");
scanf("%d %d",&x,&y);
getchar();
printf("请输入计算符号(最大公约数输入 @,最小公倍数输入 $):");
scanf("%c",&c);
// printf("计算结果为:%d\n",getValue(x,y,&c)); //*****这中形式为啥不行******
switch(c){
case '$':
printf("最小公倍数计算结果为:%d\n",getValue(x,y,"$"));
break;
case '@':
printf("最大公约数计算结果为:%d\n",getValue(x,y,"@"));
break;
case '-':
printf("它们的差计算结果为:%d\n",getValue(x,y,"-"));
break;
case '+':
printf("它们的和计算结果为:%d\n",getValue(x,y,"+"));
break;
default:
printf("输入运算符为非法字符,不能参与运算!\n");
break;
}
return 0;
}