函数指针(Day-10)
发布日期:2022-02-08 18:03:21 浏览次数:51 分类:技术文章

本文共 6048 字,大约阅读时间需要 20 分钟。

1. 函数指针

1.1 函数指针:

定义:指向函数的指针,可以通过函数指针调用指向的函数

指针类型必须与指向的数据类型一致,  函数有:返回值  函数名名  参数列表

函数指针声明: 返回值类型 (*函数指针名) (参数列表)= 函数名

函数名和数组名一样都是地址

//  例1:           int (*p)(int a, int b) = sumValue;  // sumValue是简单的两个数求和函数//  在*后面写变量名  一定要加括号       printf("%d\n", p(5, 8));//  结果是:5+8=13//  例2. 定义一个函数打印“Hello”      void (*p) ()= printHello; // 前面是void    这个只是单纯的定义      p();   //  函数指针调用// 例3. 定义两个函数,一个求最⼤值,一个求和,输⼊max或sum分别求3,5的最大值或和      char input[] = {0};      scanf("%s", input);      int (*p) (int a, int b) = NULL;      if (strcmp("sumValue", input) == 0) {          p = sumValue;      }      else if(strcmp("maxValue", input) == 0)          p = maxValue;      printf("%d  ",p(3, 5));// 结果是对的 你们可以自己测试一下

  1.2 回调函数:

回调函数过程:有点类似函数嵌套,但是回调函数的形参值是函数指针,通过函数指针,调用对应的函数,之后再返回函数指针的地方

例:  写一个函数查找90分以上的学员,使用回调函数在姓名后面加“高富帅”

Student.h:

#import 
typedef struct student{ char name[10]; float score;}Student;void search(Student *stu, void (*p) (Student *s));void addString(Student *s);
Student.m:

#import "Student.h"void search(Student *stu, void (*p) (Student *)){    if (stu->score >= 90) {        p(stu);    }}void addString(Student *s){    strcat(s->name, "高富帅");}
main.m :

int main(){    Student stu[3] = {
{"zheng", 89}, {"chen", 91}, {"fang", 94}}; for (int i = 0; i < 3; i++) { search(stu+ i, addString); printf("%s %.1f\n", stu[i].name, stu[i].score); } return 0;}
结果打印:

zheng   89.0chen高富帅   91.0fang高富帅   94.0Program ended with exit code: 0

1.3 动态排序:

#import 
typedef struct student{ char name[20]; int age; float score;}Student;
#pragma mark---------------普通的冒泡排序 START-------------------- // 学生姓名升序--------------------------------void sortOfName(Student *stu, int count){ for (int i = 0; i < count - 1; i++) { for (int j = 0; j < count - 1 - i; j++) { if (strcmp(stu[j].name, stu[j + 1].name) > 0) { Student temp = stu[j]; stu[j] = stu[j + 1]; stu[j + 1] = temp; } } } for (int i = 0; i < count; i++) { printf("%s, %d, %.1f\n", stu[i].name, stu[i].age, stu[i].score); }}// 年龄降序------------------------------void sortOfAge(Student *stu, int count){ for (int i = 0; i < count - 1; i++) { for (int j = 0; j < count - 1 - i; j++) { if (stu[j].age < stu[j + 1].age) { Student temp = stu[j]; stu[j] = stu[j + 1]; stu[j + 1] = temp; } } } for (int i = 0; i < count; i++) { printf("%s, %d, %.1f\n", stu[i].name, stu[i].age, stu[i].score); }}// 成绩升序---------------------------------void sortOfScore(Student *stu, int count){ for (int i = 0; i < count - 1; i++) { for (int j = 0; j < count - 1 - i; j++) { if (stu[j].score > stu[j + 1].score) { Student temp = stu[j]; stu[j] = stu[j + 1]; stu[j + 1] = temp; } } } for (int i = 0; i < count; i++) { printf("%s, %d, %.1f\n", stu[i].name, stu[i].age, stu[i].score); }}
//--------------------------------END--------------------------------#pragma mark-------------------动态排序 START---------------------------//两个年龄比较大小,升序BOOL compareAge(Student *s1, Student *s2){ return s1->age > s2->age;}//两个分数比较大小,降序BOOL compareScore(Student *s1, Student *s2){ return s1->score < s2->score;}//两个姓名升序排序BOOL compareName(Student *s1, Student *s2){ return strcmp(s1->name, s2->name) > 0;}//两个年龄比较大小,降序BOOL compareAge2(Student *s1, Student *s2){ return s1->age < s2->age;}typedef BOOL (*PFUN) (Student *, Student *); // PFUN = BOOL (*) (Student, Student)
// 为函数指针类型起名为PFUNvoid sortStudent(Student stus[], int count, PFUN pfun){ // 这个pfun就可以指向你自己封装的各种排序方法 for (int i = 0; i < count - 1; i++) { for (int j = 0; j < count - 1 - i; j++) { if (pfun(stus + j, stus + j + 1) == YES) { // 这里调用你写的排序方法 Student temp = stus[j]; stus[j] = stus[j + 1]; stus[j + 1] = temp; } } } for (int i = 0; i < count; i++) { printf("%s, %d, %.1f\n", stus[i].name, stus[i].age, stus[i].score); }}int main() { Student stu[5] = { {"zhang", 23, 78}, {"zhao", 11, 89}, {"bala", 22, 78.5}, {"mouse", 7, 89}, {"cat", 4, 100} };// sortOfName(stu, 5);// sortOfAge(stu, 5);// sortOfScore(stu, 5); PFUN p = compareAge2; sortStudent(stu, 5, p);
//-----------------------------------END--------------------------     return 0;}

1.4 函数指针做函数的返回值:

代码实现的功能:输入maxValue,minValue, addValue,subtractValue任意一个字符串,会实现相应代码的功能:

#import 
// 四个实现取最大值,最小值,和,差的函数int maxValue(int a, int b){ return a > b ? a : b;}int minValue(int a, int b){ return a < b ? a : b;}int addValue(int a, int b){ return a + b;}int subtractValue(int a, int b){ return a - b;}typedef int (*PFUN) (int, int); // 函数指针PFUNtypedef struct functionp{ // 结构体,成员为:name:用来存储对应函数的名字, func:存储对应函数的地址 char name[20]; PFUN func; // 函数指针}Functionp;PFUN getFunctionByName(Functionp func[], int count, char funName[]){ //  形参结构体数组func[count], 功能字符串    for (int i = 0; i < count; i++) {        if (strcmp(funName, func[i].name) == 0) {   //   找到对应结构体中的功能函数指针            return func[i].func;        }    }    return NULL;    }int main() {    Functionp f[4] = {        {"maxValue", maxValue},  //功能字符串和函数指针        {"minValue", minValue},        {"addValue", addValue},        {"subtractValue", subtractValue}    };    while (1) {        char name[30] = {0};  //  需要输入的功能字符串        printf("输入功能字符串:\n");        scanf("%s", name);        getchar();                        PFUN fun1 = NULL;  //  一个空的函数指针        fun1 = getFunctionByName(f, 4, name);        if (fun1 == NULL) {            printf("please input again\n");        }        else            printf("%s = %d  \n", name, fun1(3, 5));    }    return 0;}
 
 

结果显示:

输入功能字符串:

maxValue
maxValue = 5  
输入功能字符串:
addValue
addValue = 8  
输入功能字符串:
subtractValue
subtractValue = -2  
输入功能字符串:

转载地址:https://blog.csdn.net/Evelynzn/article/details/48542311 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:内存分配(Day-9)
下一篇:JQuery中Attr与Prop的区别

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月05日 18时27分23秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

Vue监视---vue工作笔记0005 2019-04-26
Vue条件渲染---vue工作笔记0008 2019-04-26
Vue事件处理_vue的事件处理超级方便_功能强大---vue工作笔记0011 2019-04-26
Vue表单数据自动收集---vue工作笔记0012 2019-04-26
Vue生命周期---vue工作笔记0013 2019-04-26
ES6-ES11新特性_ECMAScript_简单介绍---JavaScript_ECMAScript工作笔记001 2019-04-26
ES6-ES11新特性_ECMAScript相关名词介绍_---JavaScript_ECMAScript工作笔记002 2019-04-26
ES6新特性_let变量声明以及声明特性---JavaScript_ECMAScript_ES6-ES11新特性工作笔记003 2019-04-26
Sharding-Sphere,Sharding-JDBC_介绍_Sharding-Sphere,Sharding-JDBC分布式_分库分表工作笔记001 2019-04-26
Sharding-Sphere,Sharding-JDBC_分库分表介绍_Sharding-Sphere,Sharding-JDBC分布式_分库分表工作笔记002 2019-04-26
C++_类和对象_对象特性_构造函数的分类以及调用---C++语言工作笔记041 2019-04-26
C++_类和对象_对象特性_拷贝构造函数调用时机---C++语言工作笔记042 2019-04-26
C++_类和对象_对象特性_构造函数调用规则---C++语言工作笔记043 2019-04-26
C++_类和对象_对象特性_深拷贝与浅拷贝---C++语言工作笔记044 2019-04-26
AndroidStudio_java.util.ConcurrentModificationException---Android原生开发工作笔记237 2019-04-26
AndroidStudio_android中实现对properties文件的读写操作_不把properties文件放在assets文件夹中_支持读写---Android原生开发工作笔记238 2019-04-26
弹框没反应使用Looper解决_the caller should invoke Looper.prepare() and Looper.loop()---Android原生开发工作笔记239 2019-04-26
Command line is too long. Shorten command line for Application---微服务升级_SpringCloud Alibaba工作笔记0067 2019-04-26
AndroidStudio_android实现双击_3击_监听实现---Android原生开发工作笔记240 2019-04-26
C++_类和对象_对象特性_初始化列表---C++语言工作笔记045 2019-04-26