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 }
复制代码

 

posted on   低头捡石頭  阅读(107)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.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
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示