zoukankan      html  css  js  c++  java
  • C:函数指针、回调函数

    函数指针

     是一个指针,指向函数的指针,指针存放的都是地址,所以函数指针存放的是函数的地址。数组名就是数组的首地址,函数名就是函数的首地址。与数组类似。

    代码demo

       int (*p) (int ,int ) = NULL;
    
    // int (*) (int ,int )   这就是指针变量的类型  (除了函数名)
        p = maxValue;   指针变量存储的是函数的地址(函数名)
    
    //    定义一个有两个整形参数且返回为整型的函数指针
    #import <Foundation/Foundation.h>
    
    //    求两个数字的最大值
    //    函数的类型就是由 返回值类型 + 参数个数及类型
    int maxValue(int , int );
    int maxValue(int a , int b ){
        return a > b ? a :b ;
    }
    int minValue(int ,int );
    int minValue(int a, int b){
        return a < b ? a : b;
    }
    //char getString(); 不能这样写
    char *getString();//类型 char *     函数名  getString  返回值类型为 char * 而且没有参数的函数
    char *getString(){
    //    char a[10] = "hello";
        char *a = "hello";
        return a;
    }
    
    void outputNumber(int a); // 类型 void ()
    void outputNumber(int a){//void * 是一个泛型 返回泛型的指针 ???
        printf("
    outputNumber 输出传入数字 %d	",a);
    }
    
    
    //    定义一个函数求两个浮点数的和
    float requireTwoFloatSum(float a, float b);
    float requireTwoFloatSum(float a, float b){
        return a + b;
    }
    int main(int argc, const char * argv[]) {
       
        
    //    定义一个有两个整形参数且返回为整型的函数指针
        int (*p) (int ,int ) = NULL;
    // int (*) (int ,int )   这就是指针变量的类型 (除了函数名)
        p = maxValue; // 指针变量存储的是函数的地址(函数名)
        int value = p (20,30);
        printf("
    value = %d 	",value);
        int (*p0) (int , int ) = NULL;
        p0 = minValue;
        int min = p0(6 , 7);
        printf("
     min = %d
    ",min);
        
        
    // 分别定义函数指针,来指向对应的函数,然后使用此指针实现函数的调用
    //    char (*p1) = NULL;
    //    p1 = getString;
        char * str = getString();//没有参数小括号 不能省略
    //    练习:分别定义函数指针,来指向对应的函数,然后使用此指针实现函数的调用
        char *(*p1)() = NULL; //第二个 * 是标记 p1 是一个指针    p1的类型是char *(* )()
        printf("%s	",str);
        
        
        // outputNumber 输出传入数字
        int (*p2)(int) = NULL;
        p2 = outputNumber;
        p2(2);
        
        
    //    定义一个函数求两个浮点数的和
        float (*p3)(float ,float) = NULL;
        p3 = requireTwoFloatSum;
        float a = p3(15.44,14.33);
        printf("
    定义一个函数求两个浮点数的和 %.2f",a);
        return 0;
    }
    #import <Foundation/Foundation.h>
    
    //    定义一个函数求两个整数的和
    int requireTwoSum(int a, int b);
    int requireTwoSum(int a, int b){
        return a + b;
    }
    
    //    求两个数字的最大值
    int maxValue(int , int );
    int maxValue(int a , int b ){
        return a > b ? a :b ;
    }
    //    求两个数字的最小值
    int minValue(int ,int );
    int minValue(int a, int b){
        return a < b ? a : b;
    }
    
    //函数当成一个函数形参
    typedef int (*FUNCTION)(int ,int); //如果这里不写 typedef 的话,    typedef FUNCTION f;这句就要报错 ,typedef 只是为数据类型重命名
    //这个 FUNCTION 可以指向任意一个  int (* )(int ,int) 这种类型的函数(上面的求和,求最大值,求最小值)
    typedef FUNCTION f;
    int getValue(int ,int ,f );//声明了一个可以传递函数的函数
    int getValue(int a ,int b ,f f1 ){
        int q = f1(a,b);
        return q;
    }
    
    int main(int argc, const char * argv[]) {
       
        int arr = getValue(4, 8, maxValue);
        printf("maxValue = %d	",arr);
        int brr = getValue(23, 3, minValue);
        printf("minValue = % d	",brr);
        int crr = getValue(29, 76, requireTwoSum);
        printf("TwoSum = %d	",crr);
        
        
        return 0;
    }
    函数指针 demo

      typedef 给结构体 与 指针函数 定义新的名字的时候,要注意  把新名字存放正确的地方。typedef 只是给数据类型重新定义名字

    应用实战

    #import <Foundation/Foundation.h>
    #import "runSort.h"
    #import "teacher.h"
    
    int main(int argc, const char * argv[]) {
        /*
        Student stu[5] ={
            {"zhang san", 12 , 89},
            {"li si", 15 , 98},
            {"wang wu", 45 , 78},
            {"liu guang dan ", 18, 45},
            {"hei li qi", 11, 49}
        };
        match fun[3] = {
            {compaerByAge,"age"},
            {compaerByName,"name"},
            {compaerByScore,"score"}
        };
        compareMethood pp = getFunction(fun, 2, "name");
        sortArrAccending(stu, 5 ,pp);
         */
        Teacher teacher[5]={
            {"wang ma zi",'m',12,101,8.9},
            {"li si",'m',48,102,9.6},
            {"huang xing",'f',45,110,4.9},
            {"zhang ming",'f',46,106,10},
            {"zhang san",'f',23,109,7.5}
    
        };
        match2 fun2[6]={
            {compareNameByAscending,"namesx"},
            {compareNmaeByDescending,"namejx"},
            {compareNumByAscending,"numsx"},
            {compareNumByDescending,"numjx"},
            {compareMarkByAscending,"marksx"},
            {compareMarkByDescending,"marksx"},
        };
        compareMethood2 p2 = getFounction(fun2, 6, "numsx");
        sortTeachers(teacher,5,p2);
    
        return 0;
    }
     mian 
    #import <Foundation/Foundation.h>
    
    typedef struct teacher{
        char name[20];
        char gender;
        int  age;
        int  num;
        float mark;
    }Teacher;
    //指针函数(对比下面好多升序降序的函数)
    typedef BOOL (* compareMethood2)(Teacher teacher1,Teacher teacher2) ;
    typedef struct Match2{
        compareMethood2 Function2;
        char fname2[20];
    }match2;
    
    //打印 teacher 信息
    void  printTeacher(Teacher *  teacher);
    //函数指针类型
    typedef BOOL(*compareFunctionPointer)(Teacher teacher1,Teacher teacher2);
    //老师数组排序函数
    void sortTeachers(Teacher *teacher,int count ,compareFunctionPointer cfp);
    //声明一个打印数组中所有老师的函数
    void printTeachers(Teacher *teachers,int count);
    //两个比较姓名的函数 升序
    BOOL compareNameByAscending(Teacher teacher1, Teacher teacher2);
    //降序
    BOOL compareNmaeByDescending(Teacher teacher1, Teacher teacher2);
    //分别声明两个比较Teacher员工编号的函数 升序
    BOOL compareNumByAscending(Teacher taecher1, Teacher teacher2);
    //降序
    BOOL compareNumByDescending(Teacher teacher1,Teacher teacher2);
    //分别声明两个比较Teacher员工评分的函数 升序
    BOOL compareMarkByAscending(Teacher teacher1,Teacher teacher2);
    //降序
    BOOL compareMarkByDescending(Teacher teacher1,Teacher teacher2);
    //声明一个输出教师数组中全部男老师的函数
    void printMaleTeacher(Teacher *teacher,int count);
    //声明一个输出教师数组中全部女老师的函数
    void printFemaleTeacher(Teacher *teacher,int count);
    //条件匹配函数
    compareMethood2 getFounction(match2 * match2, int count ,char * frame2);
     teacher.h
    #import "teacher.h"
    
    //打印 teacher 信息
    void  printTeacher(Teacher * teacher){
        printf("姓名: %s 性别: %c 年龄: %d 工号: %d 评分: %.2f 
    ",teacher->name,teacher->gender,teacher->age,teacher->num,teacher->mark);
    }
    //老师数组排序函数
    void sortTeachers(Teacher *teacher,int count ,compareFunctionPointer cfp){
        if (cfp == NULL) {
            printf("没有匹配");
        }else{
            for (int i = 0; i < count - 1; i++) {
                for (int j = 0; j < count - 1 - i; j++) {
                    if (cfp(*(teacher + j),*(teacher + j + 1))) {
                        Teacher temp = *(teacher + j);
                        *(teacher + j) = *(teacher + j + 1);
                        *(teacher + j + 1) = temp;
                    }
                }
            }
        }
        printTeachers(teacher ,count);
    }
    //声明一个打印数组中所有老师的函数
    void printTeachers(Teacher *teachers,int count){
        for (int i = 0; i < count ; i++) {
            printf("姓名: %s 性别: %c 年龄: %d 工号: %d 评分: %.2f 
    ",(teachers + i)->name,(teachers + i)->gender,(teachers + i)->age,(teachers + i)->num,(teachers + i)->mark);
        }
    }
    //两个比较姓名的函数 升序
    BOOL compareNameByAscending(Teacher teacher1, Teacher teacher2){
        return strcmp(teacher1.name,teacher2.name);
    }
    //降序
    BOOL compareNmaeByDescending(Teacher teacher1, Teacher teacher2){
        return strcmp(teacher2.name, teacher1 .name);
    }
    //分别声明两个比较Teacher员工编号的函数 升序
    BOOL compareNumByAscending(Teacher teacher1, Teacher teacher2){
        return teacher1.num > teacher2.num;
    }
    //降序
    BOOL compareNumByDescending(Teacher teacher1,Teacher teacher2){
        return teacher2.num > teacher1.num;
    }
    //分别声明两个比较Teacher员工评分的函数 升序
    BOOL compareMarkByAscending(Teacher teacher1,Teacher teacher2){
        return teacher1.mark > teacher2.mark;
    }
    //降序
    BOOL compareMarkByDescending(Teacher teacher1,Teacher teacher2){
        return teacher2.mark > teacher1.mark;
    }
    //声明一个输出教师数组中全部男老师的函数
    void printMaleTeacher(Teacher *teacher,int count){
        for (int i = 0; i < count; i++) {
            if ((teacher + i)->gender == 'm') {
                printTeacher((teacher + i));
            }
        }
    }
    //声明一个输出教师数组中全部女老师的函数
    void printFemaleTeacher(Teacher *teacher,int count){
        for (int i = 0; i < count; i++) {
            if ((teacher + i)->gender == 'f') {
                printTeacher((teacher + i));
            }
        }
    }
    //条件匹配函数
    compareMethood2 getFounction(match2 * match2, int count, char *fname2){
        for (int i = 0; i < count; i++) {
            if (strcmp(match2[i].Function2, fname2)) {
                return match2[i].Function2;
                break;
            }else{
                 return NULL;
            }
        }
        return 0;
    }
     teacher.m
    #import <Foundation/Foundation.h>
    
    typedef struct{//学生信息
        char name[20];
        int  age;
        float score;
    }Student;
    typedef BOOL(*compareMethood)(Student,Student);
    typedef struct Match{
        compareMethood Function ;
        char fname[20];
    }match;
    //打印学生信息
    void outputAllStuInfo(Student *stu,int count);
    //升序排序信息
    void sortArrAccending(Student *stu,int count ,compareMethood Condition);
    //比较两者年龄
    BOOL compaerByAge(Student stu1, Student stu2);
    //比较两者成绩
    BOOL compaerByScore(Student stu1,Student stu2);
    //比较两者姓名
    BOOL compaerByName(Student stu1,Student stu2);
    //条件匹配函数
    compareMethood getFunction(match * match ,int count , char *Fname);
     runSort.h
    #import "runSort.h"
    
    //打印学生信息
    void outputAllStuInfo(Student *stu,int count){
        for (int i = 0; i < count; i++) {
            printf("name = %s ,age = %d score = %.2f
    ",(stu  + i)->name,(stu + i)->age,(stu + i)->score);
        }
    }
    
    //升序排序信息
    void sortArrAccending(Student *stu,int count,compareMethood Condition){
        if (Condition == NULL) {
            printf("没有匹配");
        }else{
            for (int i = 0; i < count - 1 ; i++) {
                for (int j = 0;j < count - 1 - i; j++) {
                    if (Condition(*(stu + j),*(stu + j + 1))) {
                        Student temp = *(stu + j);
                        *(stu + j ) =   *(stu + j + 1);
                        *(stu + j + 1) = temp;
                    }
                }
            }
        }
        outputAllStuInfo(stu, 5);
    }
    
    //比较两者年龄
    BOOL compaerByAge(Student stu1, Student stu2){
        return stu1.age > stu2.age;
    }
    
    //比较两者成绩
    BOOL compaerByScore(Student stu1,Student stu2){
        return stu1.score > stu2.score;
    }
    
    //比较两者姓名
    BOOL compaerByName(Student stu1,Student stu2){
        return strcmp(stu1.name ,stu2.name);
    }
    
    //条件匹配函数
    compareMethood getFunction(match * match ,int count , char *Fname){
        for (int i = 0; i < count; i++) {
            if (strcmp( match[i].Function , Fname)) {
                return match[i].Function;
            }else{
                return NULL;
            }
        }
        return 0;
    }
     runSort.h
  • 相关阅读:
    关于springboot项目使用yml类型的配置文件
    关于个人电脑连不上公司svn服务器,显示拒绝访问的错误
    改变思考问题的方式——SQL排序查询
    FreeMarker入门级
    个人电脑安装svn实录
    tomcat配置虚拟路径,可以解决实际开发中测试时前端访问后台电脑上的图片的问题
    springmvc的运行原理个人见解
    [CF915F] Imbalance Value of a Tree
    [CF768G] The Winds of Winter
    [BZOJ4241] 历史研究
  • 原文地址:https://www.cnblogs.com/benpaobadaniu/p/4709739.html
Copyright © 2011-2022 走看看