函数指针 : 函数回调 动态函数调用
1.指针类型和函数类型必须一致
#import <Foundation/Foundation.h>
//int maxValue(int a,int b){
// return a > b ? a : b;
//}
//int minValue(int a,int b){
// return a < b ? a : b;
//}
//
//typedef int(*pFun)(int,int);//pFun是变量类型
//
//int getValue(int a,int b,pFun p){//函数定义
// return p(a,b);
//}
///////////////1.有一学生数组,将90分以上的学⽣生姓 名后加上”(月薪过万)”////////////////
//struct student {
// float score;
// char name[50];
//};
//typedef struct student Student;
//
//void fun(char * str){//定义一个拼接字符串的函数
// strcat(str, "月薪过万");
//}
//typedef void(* pFun2)(char *);//指针类型void 和函数类型一定要一样
//
//void changeName(Student * arr,int count,pFun2 p){
// for (int i = 0; i < count; i++) {
// if (arr[i].score > 90) {
// p(arr[i].name);//函数回调相当于 fun(arr[i].name);
// }
// }
//}
//void printStudent(Student * arr,int count){
// for (int i = 0; i < count; i++) {
// printf("%.2f %s\n",arr[i].score,arr[i].name);
// }
//}
//////////////////////////////////////////////////////////////////////////
///////////////2.学⽣生结构体数组,按成绩排序、按年 龄排序,按名字排序...如何实现///////////////
struct student {
float score;
int age;
char name[50];
};
typedef struct student Stu;
typedef BOOL(*pFun)(Stu *,Stu *);//和位置没关系 类型,参数一样就行
typedef struct funPointer {
char name[50];//函数名
pFun pointer; //函数指针
}fPointer;//定义函数指针数组
BOOL scorePanduan(Stu * stu1,Stu * stu2){//成绩从高到低
return stu1->score < stu2->score;
}
BOOL agePanduan(Stu * stu1,Stu * stu2){//年龄从小到大
return stu1->age > stu2->age;
}
BOOL namePanduan(Stu * stu1,Stu * stu2){//名字从a到z
return strcmp(stu1->name, stu2->name) > 0;
}
fPointer pointer[2] = {{"成绩排序",scorePanduan},{"姓名排序",namePanduan}};//给函数指针数组赋值
pFun getFunction(fPointer * arr,int count,char * str){//(函数指针数组名,函数个数,函数名)
for (int i = 0; i < count; i++) {
if (strcmp(arr[i].name, str) == 0) {//比较传进去的名和函数指针数组中得名 如果一样
return arr[i].pointer; //返回函数指针
}
}
return NULL;//要有返回值
}
void sort(Stu * stu,int count,char * str){
pFun p = getFunction(pointer, 2, str);
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i - 1; j++) {
if(p(&stu[j],&stu[j + 1])){//if判断中函数回调
Stu temp = stu[j];
stu[j] = stu[j + 1];
stu[j + 1] = temp;
}
}
}
}
void printStudent(Stu * stu,int count){
for (int i = 0; i < count; i++) {
printf("%.2f %d %s\n",stu[i].score,stu[i].age,stu[i].name);
}
}
int main(int argc, const char * argv[])
{
// pFun p = maxValue;
// //int (*p)(int,int) = maxValue;//p保存函数maxValue的地址 p是变量名
// int max = p(3,5);//用指针名直接调用函数
// printf("max = %d\n",max);
//
// p = minValue;
// max = p(10,3);
// printf("%d\n",max);
// int value = getValue(3, 5, maxValue);
// printf("value = %d\n",value);
////// 1. /////
// Student stu[5] = {{59.9,"shenqingjun"},{99.9,"zhaoyunlong"},{91,"liuchundong"},{95,"lixiaolong"},{89.9,"liujian"}};
// changeName(stu, 5,fun);
// printStudent(stu, 5);
////// 2. /////
Stu stu[5] = {{59.9,21,"aa"},{58.9,20,"ddd"},{80,22,"ccc"},{89.9,23,"bbt"},{90,18,"drr"}};
sort(stu, 5, "姓名排序");
printStudent(stu,5);
return 0;
}
作业:
1、输⼊一句英⽂句子,将其中所有单词首字符转换成大写,用回调函数实现。(修改单词功能写成回调函数)。
void xiugai(char * str){
*str -= 32;
}
typedef void(* pFun)(char *);
void daxie(char * str,pFun xiugai){
int i = 0;
do {
scanf("%c",&str[i]);
if (i == 0 || str[i-1] == ' ' ) {
if (str[i] >= 'a' && str[i] <= 'z') {
xiugai(&str[i]);
}
}
} while (str[i++] != '\n');
}
int main(int argc, const char * argv[])
{//作业 1
char a[100] = {0};
daxie(a, xiugai);
printf("%s",a);
return 0;
}
2、动态函数调用实现下列操作,输入2个数以及操作符计算结果。
@ 求最⼤公约数 $求最小公倍数
int qiumaxGY(int a,int b){
int maxGY = 0;
for (int i = 1; i <= ((a < b) ? a : b); i++) {
if (a % i == 0 && b % i == 0) {
maxGY = i;
}
}
return maxGY;
}
int qiuminGB(int a,int b){
int minGB = 0;
minGB = a * b / qiumaxGY(a,b);
return minGB;
}
typedef int(*qiu)(int,int);
typedef struct funPointer {
char name;//函数名
qiu pointer; //函数指针
}fPointer;//定义函数指针数组
fPointer pointer[2] = {{'@',qiumaxGY},{'$',qiuminGB}};
qiu getFunction(fPointer * arr,int count,char a){//(函数指针数组名,函数个数,函数名)
for (int i = 0; i < count; i++) {
if (arr[i].name == a) {//比较传进去的名和函数指针数组中的名 如果一样
return arr[i].pointer; //返回函数指针
}
}
return NULL;//要有返回值
}
void qiuzhi(int a,int b,char c){
qiu p = getFunction(pointer, 2, c);
printf("%d\n",p(a,b));
}
int main(int argc, const char * argv[])
{
//作业 2
qiuzhi(3, 12, '@');
qiuzhi(3, 12, '$');
return 0;
}