C语言基础知识之(二十):指针高级运用

函数指针:

1、定义指针指向函数

int (*p)(int, int) = maxValue;

2、通过指针调用函数,把函数指针当做函数名使用

printf("max = %d\n", p(3, 5));结果是最大值5.

语法:

函数指针的类型  返回值类型 (*)(参数列表)

如: int(*p)(int, int);

 

例题:

定义两个函数 ,一个求最大值,一个求和,输入maxValue或sumValue分别求3,5的最大值或和。

第一步:定义两个函数

int maxValue(int a, int b);

int maxValue(int a, int b){

    return a > b ? a : b;

}

 

int sumValue(int a, int b);

int sumValue(int a, int b){

    return a+b;

}

第二步:定义一个函数指针

int (*p)(int, int) = NULL;

第三步:从控制台输入一个字符串(函数名);根据输入函数名调用不用的函数

    char name[20] = {0};

    printf("请输入函数名:\n");

    scanf("%s",name);

    getchar();//读取空格字符

 

    if (strcmp(name,"maxValue") == 0) {

        p = maxValue;

    } else if(strcmp(name,"sumValue") == 0){

        p = sumValue;

    }else{

        printf("输入的函数名不存在,请重新输入\n");

    }

   

    if (p != NULL) {//指针指向空字符会引起系统崩溃

        printf("%s =%d\n", name, p(3, 5));

}


函数回调:

1、

定义四个函数:

int maxValue(int a, int b);

int maxValue(int a, int b){

    return a > b ? a : b;

}

 

int minValue(int a, int b);

int minValue(int a, int b){

    return a < b ? a : b;

}

 

int sumValue(int a, int b);

int sumValue(int a, int b){

    return a + b;

}

 

int subValue(int a, int b);

int subValue(int a, int b){

    return a - b;

}

定义一个调用定义的4个函数的函数:

getValue函数:根据指定的运算方式,返回两个整数的运算结果

参数:前两个参数是参与运算的整数,第三个参数是进行计算的函数(实际传入的是函数的地址,使用函数指针p接收)

int getVanle(int a, int b, int (*p)(int, int));

int getVanle(int a, int b, int (*p)(int, int)){

//    函数指针p指向4个函数中的某一个

    return p(a, b);

}

使用getValue实现最大值,最小值,求和,求差

printf("max = %d\n", getVanle(3, 5, maxValue));

printf("min = %d\n", getVanle(3, 5, minValue));

printf("sum = %d\n", getVanle(3, 5, sumValue));

printf("sub = %d\n", getVanle(3, 5, subValue));

 

函数回调:在执行getValue的过程中,使用函数指针调用某个函数(使用函数指针p调用某个函数的过程)的过程。

回调函数:在getValue执行过程中,通过函数指针被调用的函数。

 

2、使用typedef定义函数指针

例题:

定义一个包含5个学生的数组,定义函数:查找成绩90分以上的学员。

1、姓名后面加“高富帅”

2、成绩加5分,如果超过100分直接设置为100分。

3、使用函数回调实现

struct student{

    char names[20];

    char sex;

    int age;

    float score;

};

typedef struct student Student;

 

//输出一个学生的函数

void printStudent(Student *s);

void printStudent(Student *s){

    printf("%-*s %c %d%.2f\n",20,  s->names, s->sex,s->age, s->score);

}

 

//输出学生数组的函数

void printAllStudent(Student *stus, int count);

void printAllStudent(Student *stus, int count){

    for (int i = 0; i <count; i++) {

        printStudent(stus+i);

    }

}

 

//姓名后面加“高富帅”

void changeName(Student *stus);

void changeName(Student *stus){

    strcat(stus->names,"高富帅");

}

 

//成绩加5分

void changeScore(Student *stus);

void changeScore(Student *stus){

    stus->score += 5;

    if (stus->score >100) {

        stus->score = 100;

    }

}

//使用typedef 定义一个函数指针

//原类型:void  (*) (Student *)    定义后新类型:PFUN

typedef  void  (*PFUN) (Student *);

 

//定义函数回调

//函数指针参数q传入相同类型函数的地址,在调用中使用原函数名,实现函数调用

void findStudent(Student *stus, int count, PFUN q);

void findStudent(Student *stus, int count, PFUN q){

    for (int i = 0; i <count; i++) {

        if (stus[i].score >90) {

            q(stus+i);

//            q(&stus[i]);

        }

    }

}

//结构体初始化

    Student stu1 = {"zhangsan", 'm', 20,87};

    Student stu2 ={"lisi", 'f', 19, 91};

    Student stu3 ={"wangwu", 'm', 21, 89};

    Student stu4 ={"zhaoliu", 'f', 22, 96};

    Student stu5 ={"qianqi", 'm', 18, 94};

//定义结构体数组

    Student stus[5] = {stu1,stu2, stu3, stu4, stu5};

   

    printAllStudent(stus, 5);

printf("\n");

 

//通过调用changeName函数,实现改名字

    findStudent(stus, 5,changeName);

    printAllStudent(stus, 5);

   

    printf("\n");

//通过调用changeName函数,实现改分数

    findStudent(stus, 5,changeScore);

printAllStudent(stus, 5);

 

 

 

 

 

 

 

 

 

 

 

 

 

函数的动态排序:

#import <Foundation/Foundation.h>

 

struct student{

    char name[20];

    char sex;

    int age;

    float score;

};

typedef struct student Student;

 

//输出某个学生的信息

void printStudent(Student *s);

void printStudent(Student *s){

    printf("%-*s %c %d%.2f\n", 10, s->name, s->sex, s->age, s->score);

}

 

//输出所有学生的信息

void showAllStudent(Student *s, int count);

void showAllStudent(Student *s, int count){

    for (int i = 0; i <count ; i++) {

        printStudent(s+i);

    }

    printf("\n");

}

 

//动态排序:定义BOOL函数,根据提供的比较结果,实现排序

//按照年龄升序排列(按照年龄比较两个学生)

BOOL compareStudentByAgeAscend(Student stu1, Student stu2);

BOOL compareStudentByAgeAscend(Student stu1, Student stu2){

    return stu1.age > stu2.age;

}

 

//按照分数降序排列

BOOL compareStudentByScoreDescend(Student stu1, Student stu2);

BOOL compareStudentByScoreDescend(Student stu1, Student stu2){

    return stu1.score <stu2.score;

}

 

//按照姓名升序

BOOL compareStudentByNameAscend(Student stu1, Student stu2);

BOOL compareStudentByNameAscend(Student stu1, Student stu2){

    return strcmp(stu1.name,stu2.name) > 0;

}

 

//按照年龄降序

BOOL compareStudentByAgeDescend(Student stu1, Student stu2);

BOOL compareStudentByAgeDescend(Student stu1, Student stu2){

    return stu1.age < stu2.age;

}

 

//定义BOOL类型的函数指针

typedef BOOL (*PFUN)(Student, Student);

 

//动态排序

void sortStudent(Student stus[ ], int count, PFUN func);

void sortStudent(Student stus[ ], int count, PFUN func){

    for (int i = 0; i <count-1; i++) {

        for (int j = 0; j <count-1-i; j++) {

            if (func(stus[j],stus[j+1])) {//根据BOOL函数的值,动态进行排序

                Student temp = stus[j];

                stus[j] =stus[j+1];

                stus[j+1] =temp;

            }

        }

    }

}

 

 

 

int main(int argc, const char * argv[]) {

   

    Student stu1 = {"zhangsan",'m', 20, 87};

    Student stu2 = {"lisi",'f', 19, 91};

    Student stu3 = {"wangwu",'m', 21, 89};

    Student stu4 = {"zhaoliu",'f', 22, 96};

    Student stu5 = {"qianqi",'m', 18, 94};

   

    Student stus[5] = {stu1,stu2, stu3, stu4, stu5};

   

    showAllStudent(stus, 5);

//学生年龄升序排列

    sortStudent(stus, 5, compareStudentByAgeAscend);

    showAllStudent(stus, 5);

//学生分数降序排列 

    sortStudent(stus, 5, compareStudentByScoreDescend);

    showAllStudent(stus, 5);

//学生姓名升序排列 

    sortStudent(stus, 5, compareStudentByNameAscend);

    showAllStudent(stus, 5);

 //学生年龄降序排列

    sortStudent(stus, 5, compareStudentByAgeDescend);

    showAllStudent(stus, 5);

   

    return 0;

}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值