• 函数指针


    1. 函数指针

    1.1 函数指针:

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

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

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

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

    复制代码
    //  例1:    
           int (*p)(int a, int b) = sumValue;  // sumValue是简单的两个数求和函数
    //  在*后面写变量名  一定要加括号
           printf("%d
    ", 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 <Foundation/Foundation.h>
    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
    ", stu[i].name, stu[i].score);
        }
        return 0;
    }
    复制代码

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

    1.3 动态排序:

    复制代码
    #import <Foundation/Foundation.h>
    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
    ", 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
    ", 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
    ", 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) 
    //  为函数指针类型起名为PFUN
    
    
    void 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
    ", 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 <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;
    }
    int addValue(int a, int b){
        return a + b;
    }
    int subtractValue(int a, int b){
        return a - b;
    }
    
    typedef int (*PFUN) (int, int); //   函数指针PFUN
    
    typedef 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("输入功能字符串:
    ");
            scanf("%s", name);
            getchar();
            
            
            PFUN fun1 = NULL;  //  一个空的函数指针
            fun1 = getFunctionByName(f, 4, name);
            if (fun1 == NULL) {
                printf("please input again
    ");
            }
            else
                printf("%s = %d  
    ", name, fun1(3, 5));
        }
        return 0;
    }
    复制代码

    结果显示:

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

  • 相关阅读:
    Sun:收购MySQL是现代软件史上最重要收购[ZT]
    SCI2012年收录的中文期刊
    Elsevier期刊投稿状态
    医学图像SCI
    贝叶斯法则,先验概率,后验概率,最大后验概率
    医学图像处理与分析方面的大牛
    2013 EI检索的国内期刊
    ICIP EMBC IUS 2013
    香港中文大学第六十九届颁授学位典礼 校长赠言 我默祷你们都能不负此生
    自动生成参考文献编号
  • 原文地址:https://www.cnblogs.com/Evelyn-zn/p/4820297.html
Copyright © 2020-2023  润新知