函数指针

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\n",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\n",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\n",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,\n",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,\n",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,\n",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;
}

 

posted @ 2016-07-27 21:13  farmerspring  阅读(193)  评论(0编辑  收藏  举报