C_Language_12

C_Language_12

函数指针:
    函数:实现某种特定功能的代码
    程序编译时,系统会将函数代码分配在代码区,这段存储空间的起始地址就是函数的地址。又称函数的指针
    函数名和数组名一样是地址
    通过函数名调用函数
    printf("%d\n",maxValue(3,5));

    函数指针:指向函数的指针。可以通过函数指针调用指向的函数
    定义函数指针指向maxValue函数
    指针类型必须与指向的数据的类型匹配,函数有类型,函数指针必须和函数的类型保持一致
    maxValue函数的类型 int(int, int)
    返回值类型(*函数指针名)(参数类型) = 函数名
    int (*p)(int x,int y) = maxValue;
    printf("%d\n",p(5,10));
    函数指针类型:返回值类型 (*)(参数类型)
例如:
        int (*)(int x,int y);
示例:void printHello(){
    printf("hello!\n");
}
定义一个可以指向上述函数的函数指针,并通过函数指针实现调用该函数
int main(int argc, const char * argv[]) {
    void (*p1)() = printHello;
    p1();
   return 0;
}
示例:定义两个函数,⼀个求最大值,⼀个求和,输⼊max或sum分别求3,5的最大值或和
         (提示,定义一个函数指针,根据输入内容指向不同函数,最后一次调用完成)。
    printf("请输入函数名max/sun:");
int maxValue(int x,int y){
    return x > y ? x : y;
}
int sumValue(int x,int y){
    return x+y;
}
int main(int argc, const char * argv[]) {
    char s[4] = {0};
    scanf("%s",s);
    getchar();
    int (*q)(int,int) = NULL;
    if (strcmp(s, "max") == 0) {
        q = maxValue;
    }
    else if (strcmp(s, "sum") == 0){
        q = sumValue;
    }else{
        printf("输入的函数名不存在\n");
    }
    int a = 3;int b = 15;
    printf("%d\n",q(a,b));
   return 0;
}

回调函数:
    函数指针作为函数参数
int maxValue(int x,int y){
    return x > y ? x : y;
}
int sumValue(int x,int y){
    return x+y;
}
int main(int argc, const char * argv[]) {
    //int(*)(int,int)
    int(*p)(int, int) = maxValue;
    int (*q)(int, int) = sumValue;
    printf("%d\n",getValue(4, 9, p));
    printf("%d\n",getValue(4, 9, q));
   return 0;
}

    函数回调过程:在getValue执行的过程中,通过传入的函数指针,调用执行某个函数
    回调函数:在函数执行过程中,通过函数指针被调用的函数
    函数回调:调用回调函数的操作

示例:写一函数查找成绩90分以上的学员,使⽤回调函数在姓名后加”高富帅”。
typedef struct student{
    int num;
    char name[30];
    float socer;
}Student;
void CatOfraw(Student *s){
    strcat(s->name, "---高富帅");
}
void  inquireUpto90score(Student *s,void(*p)(Student *)){
    if (s->socer >= 90) {
        p(s);
    }
    printf("No.%d Name:%-20s Socre:%f\n",s->num,s->name,s->socer);
}
int main(int argc, const char * argv[]) {
    Student stu[5] = {{1001,"litongxue",96.5},
                      {1002,"liutongxue",97.5},
                      {1003,"wangtongxue",70.5},
                      {1004,"zhaotongxue",86.5},
                      {1005,"suntongxue",91.5}};
    Student *t = stu;
    void (*p)(Student *) = CatOfraw;
    void  (*q)(Student *s,void(*p)(Student *)) = inquireUpto90score;
    for (int i = 0; i < 5; i++) {
        q(t+i,p);
    }
   return 0;
}

动态排序:
    动态排序:排序的规则不同,年龄、姓名、成绩、升序、降序
    利用回调函数实现动态排序
示例:
根据名字大小排
根据成绩大小排
根据年龄大小排
typedef struct student1{
    char name[20];
    char sex[3];
    int age;
    float score;
}Student1;
void sortStaudentByName(Student1 *stus,int count){
    for (int i = 0; i < count -1; i++) {
        for (int j = 0; j < count -i -1; j++) {
            if (strcmp(stus[j].name, stus[j+1].name) > 0) {
                Student1 temp = stus[j];
                stus[j] = stus[j+1];
                stus[j+1] = temp;
            }
        }
    }
}
void sortStaudentByScore(Student1 *stus,int count){
    for (int i = 0; i < count -1; i++) {
        for (int j = 0; j < count -i -1; j++) {
            if (stus[j].score < stus[j+1].score) {
                Student1 temp = stus[j];
                stus[j] = stus[j+1];
                stus[j+1] = temp;
            }
        }
    }
}
void sortStaudentByAge(Student1 *stus,int count){
    for (int i = 0; i < count -1; i++) {
        for (int j = 0; j < count -i -1; j++) {
            if (stus[j].age < stus[j+1].age) {
                Student1 temp = stus[j];
                stus[j] = stus[j+1];
                stus[j+1] = temp;
            }
        }
    }
}
void printfAllstudent(Student1 * s,int count){
    for (int i = 0; i < count; i++) {
        printf("Name:%-8s sex:%s age:%d Socre:%f\n",(s+i)->name,(s+i)->sex,(s+i)->age,(s+i)->score);
    }
}

void sortStaudentByName(Student1 *stus,int count);//声明
void sortStaudentByScore(Student1 *stus,int count);
void sortStaudentByAge(Student1 *stus,int count);
void printfAllstudent(Student1 * s,int count);

void sortStudent(Student1 *stus,int count,SORT p_sort);
BOOL compareStudentByName(Student1 stu1,Student1 stu2);
BOOL compareStudentByScore(Student1 stu1,Student1 stu2);
BOOL compareStudentByAge(Student1 stu1,Student1 stu2);

//声明和改名
typedef BOOL (*SORT)(Student1,Student1);
//    SORT 代表的是一个函数指针类型,指向的函数的返回值是BOOL类型,参数是两个Student1变量

//    实现排序函数
void sortStudent(Student1 *stus,int count,SORT p_sort){
    for (int i = 0; i < count-1; i++) {
        for (int j = 0; j < count-i-1; j++) {
            if (p_sort(stus[j],stus[j+1])) {
                Student1 temp = stus[j];
                stus[j] = stus[j+1];
                stus[j+1] = temp;
            }
        }
    }
}

BOOL compareStudentByName(Student1 stu1,Student1 stu2)
{
    return strcmp(stu1.name, stu2.name) > 0;
}
BOOL compareStudentByScore(Student1 stu1,Student1 stu2)
{
    return stu1.score > stu2.score;
}
BOOL compareStudentByAge(Student1 stu1,Student1 stu2)
{
    return stu1.age > stu2.age;
}

int main(int argc, const char * argv[]) {
        Student1 stus[5] = {{"wukong", "男", 500, 60.0},
                            {"zixia", "女", 18, 98.0},
                            {"sanzang", "男", 40, 100.0},
                            {"longma", "女", 27, 93.0},
                            {"bajie", "女", 300, 59.0}};
        printf("\n按姓名排序\n");
        sortStaudentByName(stus, 5);
        printfAllstudent(stus, 5);
        printf("\n按分数排序\n");
        sortStaudentByScore(stus, 5);
        printfAllstudent(stus, 5);
        printf("\n按年龄排序\n");
        sortStaudentByAge(stus, 5);
        printfAllstudent(stus, 5);
    
            printf("\n新玩法!\n");
            printf("\n按姓名排序\n");
            sortStudent(stus, 5, compareStudentByName);
            printfAllstudent(stus, 5);
            printf("\n按分数排序\n");
            sortStudent(stus, 5, compareStudentByScore);
            printfAllstudent(stus, 5);
            printf("\n按年龄排序\n");
            sortStudent(stus, 5, compareStudentByAge);
            printfAllstudent(stus, 5);
       return 0;
}

函数的返回值是函数指针:

示例:
typedef int (*PFunnc)(int,int);

int maxValue(int x,int y);
int minValue(int x,int y);
int sumValue(int x,int y);
int subValue(int x,int y);
int getValue(int x,int y,int(*p)(int ,int));
int getValue1(int a,int b,PFunnc p);
PFunnc getFunctionName(char funName[]);

int maxValue(int x,int y){
    return x > y ? x : y;
}
int minValue(int x,int y){
    return x < y ? x : y;
}
int sumValue(int x,int y){
    return x+y;
}
int subValue(int x,int y){
    return x-y;
}
int getValue(int x,int y,int(*p)(int ,int)){
    //    p是函数指针,具体指向那个函数,由调用函数时传入的函数名决定
    int r = p(x,y);
    return r;
}
int getValue1(int a,int b,PFunnc p){
    return p(a,b);
}
PFunnc getFunctionName(char funName[]){
    if (strcmp(funName, "sumValue") == 0){
        return sumValue;
    }
    if (strcmp(funName, "subValue") == 0){
        return subValue;
    }
    if (strcmp(funName, "maxValue") == 0){
        return maxValue;
    }
    if (strcmp(funName, "minValue") == 0){
        return minValue;
    }
    return NULL;
}

从控制台输入函数名
int main(int argc, const char * argv[]) {
        while (YES) {
            printf("请输入sumValue/subValue/maxValue/minValue中的函数名:");
            char name[20] = {0};
            scanf("%s",name);
            getchar();
            PFunnc p = getFunctionName(name);
            if (p != NULL) {
                int result = getValue(3, 7, p);
                printf("%s %d\n",name,result);
            }
        }
    return 0;
}

posted @ 2015-12-03 20:33  DH_Fantasy  阅读(96)  评论(0)    收藏  举报