• 函数指针


    1.在C语言中,函数名也是指针变量,创建一个a()函数的同时也会创建一个叫a的指针变量,变量中保存了函数的地址。

    2.函数指针: 返回类型(*指针变量)(参数类型)

           int (*match)(char*)

    3.void指针可以保存任何类型的指针

    4.函数指针数组:

      返回类型(*指针变量)(参数类型)

       例如:enum response_type{DUMP,SECOND_CHANCE,MARRIAGE};

      写成:viod(*replies[])(response) = {dump,second_chance,marriage};    

    *注意:在数组中,函数名的顺序与枚举类型的顺序完全相同,因为当c语言在创建枚举时会给每个符号分配一个从0开始的数字,所以DUMP == 0;也就是说可以用respond_type获取数组中的函数指针。

    replies[SECOND_CHANCE] == second_chance

     举例

    int main()
    {
        response r[] = 
        {
            {"Mike",DUMP},{"Luis",SECOND_CHANCE},
            {"Matt",SECOND_CHANCE},{"William",MARRIAGE}
        };
        int i;
        for(i = 0;i < 4;i++)
        {
        switch(r[i].type)
        {
        case DUMP:
            dump(r[i]);
            break;
        case SECOND_CHANCE:
            second_chance(r[i]);
            break;
        default:
            marriage(r[i]);
        }
        }
        return 0;
    }

    可以改写成(便于增加新的回复类型,使代码易于伸缩)

    void (*replies[])(response) = {dump,second_chance,marriage};
    int main()
    {
        response r[] = 
        {
            {"Mike",DUMP},{"Luis",SECOND_CHANCE},
            {"Matt",SECOND_CHANCE},{"William",MARRIAGE}
        };
        int i;
        for(i = 0;i < 4;i++)
        {
            (*replies[r[i].type])(r[i]);//*replies[r[i].type]是所指向的那个函数
        }
        return 0;
    }

     5.函数指针是唯一不需要加*和&运算符的指针(也可以加上)

    练习使用函数指针

    #include<stdio.h>
    #include<stdlib.h>
    
    int NUM_ADS = 7;
    char *ADS[] = 
    {
        "William:SBM GSOH likes sports,TV,dining.",
        "Matt:SWM NS likes art,movies,theater.",
        "Luis:SLM ND likes book,theater,art.",
        "Mike:DWM DS likes trucks,sports and bieber.",
        "Peter:SAM likes chess,working out and art.",
        "Josh:SJM likes sports,movies and theater.",
        "Jed:DBM likes theater,books and dining."
    };
    
    int sports_no_bieber(char *s)
    {
        return strstr(s,"sports") && !strstr(s,"bieber");
    }
    
    int sports_or_workout(char *s)
    {
        return strstr(s,"sports") || strstr(s,"working out");
    }
    
    int ns_theater(char *s)
    {
        return strstr(s,"NS") && strstr(s,"theater");
    }
    
    int arts_theater_or_dining(char *s)
    {
        return strstr(s,"arts") || strstr(s,"theater") || strstr(s,"dining");
    }
    
    void find(int (*match)(char*))//名为match的指针,指向一个函数
    {
        int i;
        puts("Search results:");
        puts("----------------------------");
        for (i = 0;i < NUM_ADS;i++)
        {
            if(match(ADS[i]))   //可以写成(*match)(ADS[i])
                printf("%s
    ",ADS[i]);
        }
        puts("----------------------------");
    }
    
    int main()
    {
        find(sports_no_bieber);  //可以写成find(&sports_no_bieber);
        find(sports_or_workout);
        find(ns_theater);
        find(arts_theater_or_dining);
        return 0;
    }

    练习二

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    qsort(void *array,
          size_t length,
          size_t item_size,
          int (*compar)(const void *,const void *));
    
    //升序排列整数
    int compare_scores(const void * score_a,const void * score_b)
    {
        int a = *(int*)score_a;//把void型指针转化为int型指针
        int b = *(int*)score_b;
        return a - b;
    }
    
    //降序排列整型得分
    int compare_scores_desc(const void * score_a,const void * score_b)
    {
        int a = *(int*)score_a;
        int b = *(int*)score_b;
        return b - a;
    }
    
    //按面积从小到大排列矩形
    typedef struct
    {
        int width;
        int height;
    }rectangle;
    
    int compare_areas(const void *a,const void *b)
    {
        rectangle *ra = (rectangle*)a;
        rectangle *rb = (rectangle*)b;
        int area_a = ra->width * ra->height;
        int area_b = rb->width * rb->height;
        return area_a - area_b;    
    }
    
    //按字母排列名字,区分大小写
    int compare_name(const void *a,const void *b)
    {
        char** ra = (char**)a;
        char** rb = (char**)b;//字符串是字符指针,所以得到的是指针的指针
        return strcmp(*ra,*rb);
    }
    
    //按面积从大到小排列矩形
    int compare_areas_desc(const void *a,const void *b)
    {
        return compare_areas(b,a);//可以写成 -compare_areas(a,b)    
    }
    
    //按逆字母排列名字,区分大小写
    int compare_name_desc(const void *a,const void *b)
    {
        return compare_names(b,a);//可以写成 -compare_names(a,b)
    }
    
    int main()
    {
        int scores[] = {543,323,32,554,11,3,112};
        int i;
        qsort(scores,7,sizeof(int),comepare_scores_desc);
        puts("These are the scores in order:");
        for(i = 0;i < 7;i++)
            printf("Score = %i
    ",scores[i]);
        char *names[] = {"Karen","Mark","Brett","Molly"};
        qsort(names,4,sizeof(char*),compare_names);
        puts("These are the names in order:");
        for(i = 0;i < 4;i++)
            printf("%s
    ",names[i]);
        return 0;
    }

     练习三

    #include <stdio.h>
    
    enum response_type{DUMP,SECOND_CHANCE,MARRIAGE};
    typedef struct
    {
        char *name;
        enum reponse_type type;
    }response;
    
    void dump(response r)
    {
        printf("Dear %s,
    ",r.name);
        puts("Unfortunately your last date contacted us to");
        puts("say that they will not be seeing you again");
    }
    
    void second_chance(response r)
    {
        printf("Dear %s,
    ",r.name);
        puts("Good news: your last date has asked us to");
        puts("arrange another meeting. Please call ASAP");
    }
    
    void marriage(response r)
    {
        printf("Dear %s,
    ",r.name);
        puts("Congratulations! Your last date has contacted");
        puts("us with a proposal of marriage.");
    }
    
    int main()
    {
        response r[] = 
        {
            {"Mike",DUMP},{"Luis",SECOND_CHANCE},
            {"Matt",SECOND_CHANCE},{"William",MARRIAGE}
        };
        int i;
        for(i = 0;i < 4;i++)
        {
        switch(r[i].type)
        {
        case DUMP:
            dump(r[i]);
            break;
        case SECOND_CHANCE:
            second_chance(r[i]);
            break;
        default:
            marriage(r[i]);
        }
        }
        return 0;
    }
  • 相关阅读:
    scrapy+Lucene搭建小型搜索引擎
    普通程序员如何转向AI方向
    python:单引号,双引号和三引号
    【推荐】你必须知道的EF知识和经验
    Quartz.NET 入门
    论如何学习一门编程语言
    Android解析ActivityManagerService(一)AMS启动流程和AMS家族
    python的数据可视化库 matplotlib 和 pyecharts
    pythonWeb -- Django开发- Admin
    Android内存优化(四)解析Memory Monitor、Allocation Tracker和Heap Dump
  • 原文地址:https://www.cnblogs.com/syyy/p/5712652.html
Copyright © 2020-2023  润新知