C语言 - 训练营:函数指针用作参数(动态调用函数)
函数指针用作参数
1 - 代码示例
① 使用函数指针实现函数的动态调用
1 #include <stdio.h> 2 // 定义 BOOL 变量 3 typedef enum{ 4 false, 5 true 6 }BOOL; 7 8 // 存储学生信息 9 typedef struct stu{ 10 11 char name[50]; 12 int age; 13 float score; 14 15 }Student; 16 17 18 // 打印学生原有信息 19 void printOriginalStudent(Student *s,int count){ 20 21 printf("=======================\n原学生信息\n\n"); 22 for (int i = 0; i < count; i++) { 23 24 printf("%s %d %.2f\n",s[i].name,s[i].age,s[i].score); 25 }; 26 printf("\n=======================\n"); 27 } 28 29 // 按年龄排序 30 // @count 学生总数 31 // 问题:一旦需求发生改变,如现在要按照性别或分数排序,很明显地这种写法就很不灵活 32 void sortByAge(Student *stu, int count){ 33 34 35 // 冒泡 36 for (int i = 0; i < count -1; i++) { 37 for (int j = 0; j < count - 1 -i; j++) { 38 39 if (stu[j].age > stu[j+1].age) { 40 Student temStu = stu[j]; 41 stu[j] = stu[j+1]; 42 stu[j+1] = temStu; 43 } 44 } 45 } 46 47 printf("按年龄升序\n\n"); 48 for (int i = 0; i < count; i++) { 49 50 printf("%s %d %.2f\n",stu[i].name,stu[i].age,stu[i].score); 51 }; 52 } 53 54 //-------------------- 动态调用函数 --------------------- 55 // 思路:函数作参,需要哪个功能就传哪个函数 56 // 步骤一:首先要搞出对应功能的函数 57 // 按年龄排序 58 BOOL sortWithAge(Student s1,Student s2){ 59 return s1.age > s2.age; 60 } 61 62 // 按分数排序 63 BOOL sortWithScore(Student s1,Student s2){ 64 return s1.score > s2.score; 65 } 66 67 // 按姓名排序 68 BOOL sortWithName(Student s1,Student s2){ 69 70 return strcmp(s1.name,s2.name)>0 ? 1 : 0; 71 } 72 73 // 步骤二:函数作参 74 // 方式 ①:不使用 typedef 关键字 75 void sortStudent01(Student *stu,int count,BOOL(*sortDemo)(Student s1,Student s2)){ 76 77 for (int i = 0; i < count -1; i++) { 78 for (int j = 0; j < count - 1 -i; j++) { 79 80 // 调用函数返回结果 81 if (sortDemo(stu[j],stu[j+1])) { 82 Student temStu = stu[j]; 83 stu[j] = stu[j+1]; 84 stu[j+1] = temStu; 85 } 86 } 87 } 88 } 89 90 // 方式 ②:使用 typedef 关键字 91 // @methodName 无实际意义,仅调用时传入固定字符串,方便查看日志信息 92 typedef BOOL(*SORT)(Student s1,Student s2); 93 void sortStudent(Student *stu,int count,SORT st,char methodName[20]){ 94 95 for (int i = 0; i < count -1; i++) { 96 for (int j = 0; j < count - 1 -i; j++) { 97 98 // 调用函数返回结果 99 if (st(stu[j],stu[j+1])) { 100 Student temStu = stu[j]; 101 stu[j] = stu[j+1]; 102 stu[j+1] = temStu; 103 } 104 } 105 } 106 107 printf("----------------\n按照 %s 进行排序\n\n",methodName); 108 for (int i = 0; i < count; i++) { 109 110 printf("%s %d %.2f\n",stu[i].name,stu[i].age,stu[i].score); 111 }; 112 } 113 114 int main(int argc, const char * argv[]) { 115 116 // -------------- 原有的学生信息 -------------- 117 Student stu[] = { 118 {"zhangsan",13,19.3}, 119 {"lisi",15,18.3}, 120 {"wangwu",11,12.9}, 121 {"zhaoliu",14,11.1} 122 }; 123 124 printOriginalStudent(stu, sizeof(stu)/sizeof(stu[0])); 125 sortByAge(stu,4); 126 127 //---------------- 排序 ---------------- 128 // 只需要输入函数名,就可以执行相应的函数 129 sortStudent(stu, 4, sortWithAge,"age"); 130 sortStudent(stu, 4, sortWithScore,"score"); 131 sortStudent(stu, 4, sortWithName,"name"); 132 133 return 0; 134 }
日志打印
② 根据字符串调用相应的函数
1 #include <stdio.h> 2 // ----------步骤 ①:确定方法并声明同类型的函数指针 3 // 最大值 4 int maxValue(int a,int b){ 5 return a > b? a : b; 6 } 7 8 // 最小值 9 int minValue(int a,int b){ 10 return a > b ? b : a; 11 } 12 13 // 搞一个错误提示 14 int errorMessage(int x,int y){ 15 printf("未找到将要调用的函数\n"); 16 return 0; 17 } 18 19 // 声明函数指针 20 typedef int (*PFUN)(int a,int b); 21 22 23 // -----------步骤 ② 24 // 搞一个结构体,包含字符串(函数名)、指向该函数的指针 25 typedef struct nameFunctionPair{ 26 char name[20]; 27 PFUN functionDemo; 28 }NFPDemo; 29 30 // 把方法放进结构体 31 NFPDemo nfp[2] = { 32 33 {"max",maxValue}, 34 {"min",minValue} 35 }; 36 37 // -------------步骤 ③:定义一个新的函数,返回值是函数指针 38 PFUN getFunctionWithName(char name[]){ 39 40 for (int i = 0; i <2; i ++) { 41 // 不匹配则按照失败处理 42 if (strcmp(nfp[i].name, name) == 0) { 43 return nfp[i].functionDemo; 44 } 45 } 46 47 // 返回错误信息 48 return errorMessage; 49 }; 50 51 int main(int argc, const char * argv[]) { 52 53 // 根据字符串调用相应的函数 54 55 PFUN pp = getFunctionWithName("max"); // 正常 56 PFUN QQ = getFunctionWithName("mmm"); // 异常 57 58 59 printf("%d\n%d\n", pp(30,40),QQ(300,400)); 60 return 0; 61 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2018-04-08 UI基础 - UIPickerView
2018-04-08 UI基础 - UISearchBar
2018-04-08 UI基础 - UITextView
2018-04-08 UI基础 - UIWebView | 已弃用 |
2018-04-08 UI基础 - UISegmentedControl