12-函数指针,函数回调,动态内存排序

来源:互联网 发布:支持windows的手机 编辑:程序博客网 时间:2024/06/04 19:01

// 函数指针???

void fun1();

void fun1()

{

    // 定义:函数指针是指针,是指向函数的指针

    // 函数名称和数组名称一样,都是代表首地址

    printf("fun1 = %p\n", fun1);

    // 注意:函数被编译完成后被存放在内存中的代码区

    

   

    

    

    // 函数指针的写法:

    // 1. 赋值函数声明

    // 2. 去除函数名,换成一对'()',里面加上'*',再加变量名

    // 3. 赋初始为NULL

    //  1. void fun1()

    //  2. void (*p)()

    //  3. void (*p)() = NULL;

    void (*p)() = NULL;

    // 函数指针定义,p是变量,其它是类型(通常没有形参a,b)

    

    // 给函数指针赋值函数名

    p = fun1;

    // 函数指针当函数名使用

    p(); // 调用函数,使用指针来调用

}




// 练习1

void printHello();

void printHello()

{

    printf("Hello\n");

}


void practice1();

void practice1()

{

    // 定义一个可以指向上述函数的函数指针,并通过函数指针实现调用该函数

    // 1. 函数指针类型

    void (*hello)() = NULL;     // 创建函数指针变量

    hello = printHello;         // 给函数指针赋值

    hello();                    // 使用指针,调用函数

}




// 练习2

// 求和函数

int sum(int a, int b);

int sum(int a, int b)

{

    return a + b;

}


// 求最大值

int maxValue(int a, int b);

int maxValue(int a, int b)

{

    return a > b ? a : b;

}


void practice2();

void practice2()

{

    // 定义两个函数,一个求最大值,一个求和,输入maxValuesum分别求3,5的最大值或和(提示,定义一个函数指针,根据输入内容指向不同函数,最后一次调用完成)

    

    // 定义函数指针

    int a = 0, b = 0, result = 0, choose = 0;

    int (*p) (intint) = NULL;

    

    printf("请输入第一个数:");

    scanf("%d", &a);

    printf("请输入第二个数:");

    scanf("%d", &b);

    printf("~~~~~~~~~~\n");

    printf("1. 求和\n");

    printf("2. 求最大值\n");

    printf("~~~~~~~~~~\n");

    printf("请选择:");

    scanf("%d", &choose);

    

    switch (choose) {

        case 1: {

            p = sum;

            break;

        }

        case 2: {

            p = maxValue;

            break;

        }

        default: {

            printf("输入错误(默认求和)\n");

            p = sum;

            break;

        }

    }

    // 使用指针进行函数的调用

    result = p(a, b);

    printf("result = %d\n", result);

}





// 函数回调(函数指针作为参数)

// 返回值:int类型

// 函数名:getValue

// 参数列表:1.aint类型)  2.bint类型)  3.p int(*)(int, int)类型,函数指针)

int getValue(int a, int b, int (*p)(intint));

int getValue(int a, int b, int (*p)(intint))

{

    // 使用函数指针去调用函数,此时,执行的时候到底调用哪个函数还不知道,看你传进来的函数指针指向的是哪个函数

    return p(a, b);

}




// 练习3

// 写一函数查找成绩90分以上的学员,使用回调函数在姓名后加高富帅

typedef struct {

    char name[30];  // 姓名

    int age;        // 年龄

    float score;    // 分数

} Student;


// 打印所有学生的函数

void printStudents(Student *stus, int count);

void printStudents(Student *stus, int count)

{

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

        printf("name = %-15s age = %-4d score = %-5.2f\n", (stus + i)->name, (stus + i)->age, (stus + i)->score);

    }

}


// 修改学生姓名函数

void changeStudentName(Student *stu);

void changeStudentName(Student *stu)

{

    strcat(stu->name"~高富帅");

}


// 函数两个参数:

// 1. 学生数组

// 2. 修改姓名的函数指针

void practice3(Student *stus, int count, void(*p)(Student *stu));

void practice3(Student *stus, int count, void(*p)(Student *stu))

{

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

        // 判断当前学生分数是否大于90

        if ((stus + i)->score >= 90) {

            // 使用指针调用函数

            p((stus + i));

        }

    }

}







// 动态排序

// 为函数指针起别名

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


// 按姓名排序

BOOL sortByName(Student *stu1, Student *stu2);

BOOL sortByName(Student *stu1, Student *stu2)

{

    if (strcmp(stu1->name, stu2->name) > 0) {

        return YES;

    }

    return NO;

}


// 按年龄排序

BOOL sortByAge(Student *stu1, Student *stu2);

BOOL sortByAge(Student *stu1, Student *stu2)

{

    if (stu1->age > stu2->age) {

        return YES;

    }

    return NO;

}


// 按分数排序

BOOL sortByScore(Student *stu1, Student *stu2);

BOOL sortByScore(Student *stu1, Student *stu2)

{

    if (stu1->score > stu2->score) {

        return YES;

    }

    return NO;

}






// 动态排序,排序函数

void sortStudents(Student *stus,int count, PFUN p);

void sortStudents(Student *stus,int count, PFUN p)

{

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

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

            // if中的条件取决于函数指针指向的函数

            if (p(stus + j , stus + j + 1)) {

                Student tempStu = stus[j];

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

                stus[j + 1] = tempStu;

            }

        }

    }

}






// 函数返回值是函数指针

int min(int a, int b);

int min(int a, int b)

{

    return a > b ? b : a;

}

int max(int a, int b);

int max(int a, int b)

{

    return a > b ? a : b;

}


// 给函数指针起个别名

typedef int (*PFUN2) (intint);

// 结构体指针与其对应的字符串

typedef struct {

    char name[30];      // 函数名字符串形式

    PFUN2 function;     // 函数指针

} NameFunctionPair;


PFUN2 getFunctionByName(char *name);

PFUN2 getFunctionByName(char *name)

{

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

        return min;

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

        return max;

    }

    return NULL;

}





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

{


    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // 函数指针作为参数的调用

    int (*p)(intint) = NULL;

    p = sum;

    // p = maxValue;

    // 调用getValue函数的时候,具体是返回和还是最大值取决于函数指针p的指向的函数

    int result = getValue(10, 20, p);

    // printf("result = %d\n", result);

    

    

    

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // 练习3

    Student stus[] = {

        {"张赛赛", 18, 89.9},

        {"王赛赛", 12, 29.1},

        {"李赛赛", 41, 100.0},

        {"赵赛赛", 89, 96.9}

    };

    // 指向修改学生姓名函数的指针

    void (*p2)(Student *) = changeStudentName;

    // 数组元素个数

    int stusCount = sizeof(stus) / sizeof(Student);

    // 修改之前打印

    printf("\n修改之前:\n");

    printStudents(stus, stusCount);

    // 修改

    practice3(stus, stusCount, p2);

    // 修改之后打印

    printf("\n修改之后:\n");

    printStudents(stus, stusCount);

    

    

    

    

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    printf("\n\n\n");

    // 动态排序

    Student students[] = {

        {"xiaohong", 19, 90.5},

        {"xiaolv", 25, 100.0},

        {"xiaolan", 14, 23.5},

        {"xiaobai", 26, 10.0},

        {"xiaoqing", 12, 56.4}

    };

    // 数组长度

    int studentsCount = sizeof(students) / sizeof(Student);

    // 排序之前

    printf("\n排序之前:\n");

    printStudents(students, studentsCount);

    // 函数指针,负责制定排序方式

    PFUN p3 = NULL;

    p3 = sortByAge;     // 根据年龄排序

    p3 = sortByName   // 根据姓名排序

    p3 = sortByScore;   // 根据分数排序

    // 排序

    sortStudents(students, studentsCount, p3);

    // 排序之后

    printf("\n排序之后:\n");

    printStudents(students, studentsCount);

    

    

    

    

    

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // 数据结构

    NameFunctionPair nameFunctionPair[] = {

        {"min"min},

        {"max"max}

    };

    // 根据字符串去获取函数名称

    PFUN2 fun = NULL;

    fun = getFunctionByName(nameFunctionPair[0].name);

    // 使用指针调用返回的函数

    int result2 = fun(100, 30);

    printf("\nresult2 = %d\n", result2);

    

    

    

    

    

    return 0;

}


0 0
原创粉丝点击