C语言高级函数使用

函数的指针

当你创建一个函数test的时候,同时也会创建test的指针变量,变量中保存了函数的地址

创建函数指针

int(*warp_fn)(int);     #创建warp_fn的变量,用来保存test()函数的地址
warp_fn = test;
warp_fn(4);             #等同于调用test函数

char** (*names_fn)(char*, int);                     #创建一个names_fn的变量用来保存test函数
names_fn = test;
char** results = name_fn(1972);

函数指针应用

#include <stdio.h>
#include <string.h>

int NUM_ADS = 7;
char *ADS[] = {
    "William:SBM GSON likes sport,TV,dining",
    "Matt:SWM NS likes art,movies,theather",
    "Luis:SLM ND likes books,theater,art",
    "MIKE:DWM DS likes truncks,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"
};
/**
 * 都要定义哦
 */
void find();
int sports_no_bieber(char *s);
int sports_or_workout(char *s);
int ns_theater(char *s);

int main()
{
    find(sports_no_bieber);
    find(sports_or_workout);
    find(ns_theater);
    return 0;
}

/**
 * 注意find中传入的参数是函数的指针
 * char** 表示返回类型
 * *func 表示指针变量
 * char* 表示参数类型
 */
void find(char** (*func)(char*))
{
    int i;
    puts("Search results:");
    puts("---------------------");

    for(i=0;i<NUM_ADS;i++) {
        if (func(ADS[i])) {
            printf("%s\n", ADS[i]);
        }
    }

    puts("----------------");
}

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");
}

qsort使用

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compare_scores(const void * scores_a, const void * scores_b);

typedef struct {
    int width;
    int height;
} rectangle;

int compare_areas(const void* a, const void* b);

int compare_name(const void* a, const void* b);

int main()
{
    int scores[] = {2,3,123,345,456,7,11,3,5,6};
    qsort(scores, 10, sizeof(int), compare_scores);
    int i;

    for(i=0;i<10;i++) {
        printf("%i\n", scores[i]);
    }

    int areas[] = {2,3,345,123,1};
    qsort(areas, 5, sizeof(int), compare_areas);
    int x;

    for(x=0;x<5;x++) {
        printf("%i\n", areas[x]);
    }

    char *names[] = {"c", "a","b"};
    qsort(names, 3, sizeof(char*), compare_name);
    int z;

    for(z=0;z<3;z++) {
        printf("%s\n", names[z]);
    }

    return 0;
}

/**
    void指针可以保存任何类型数据的地址,但使用前必须把它转换成具体类型
*/
int compare_scores(const void * scores_a, const void * scores_b)
{
    /**
        int * 把void指针转换成整形指针
        *(int *)获取获取scores_a中的整形值
    */
    int a = *(int *)scores_a;
    int b = *(int *)scores_b;

    return b-a;
}

int compare_areas(const void *a, const void *b)
{
    /**
        把指针转换成相应的类型
    */
    rectangle *ia = (rectangle*)a;
    rectangle *ib = (rectangle*)b;
    /**
        矩形面积计算
    */
    int area_a = (ia->width * ia->height);
    int area_b = (ia->width * ia->height);

    return area_a-area_b;
}

int compare_name(const void* a, const void* b)
{
    /**
        char** 代表的是指向字符指针的指针
    */
    char** sa = (char**)a;
    char** sb = (char**)b;

    /**
        strcmp接收的是char*的值,而char**是指针地址
    */
    return strcmp(*sa, *sb);
}

函数指针

void(*function_name[])(response)={function_a,function_b};
void            声明返回类型
*               声明函数指针
function_name   变量名
[]              表明是函数数组
response        参数类型
例子:
    #include <stdio.h>

    enum response_type {DUMP, SECOND_CHANCE, MARRIAGE};

    typedef struct {
        char* name;
        enum response_type type;
    }response;

    void dump(response r);
    void second_chance(response r);
    void marriage(response r);

    int main()
    {
        response ra[] = {
            {"test", DUMP},
            {"test2", SECOND_CHANCE},
        };

        /**
            定义函数数组
        */
        void(*func_arr[])(response) = {dump, second_chance, marriage};

        int i;
        for (i=0;i<2;i++) {
            /**
                使用函数数组定义的方法
            */
            (func_arr[ra[i].type])(ra[i]);

            /**
                受用switch的方法
            */
            switch(ra[i].type) {
                case DUMP:
                    dump(ra[i]);
                break;
                case SECOND_CHANCE:
                    second_chance(ra[i]);
                break;
                default:
                    marriage(ra[i]);
                break;
            }
        }

        return 0;
    }

    void dump(response r)
    {
        printf("hello,i'm dump, you are %s\n", r.name);
    }

    void second_chance(response r)
    {
        printf("hello,i'm second_chance, you are %s\n", r.name);
    }

    void marriage(response r)
    {
        printf("hello,i'm marriage, you are %s\n", r.name);
    }

可变参数个数

在C标准库中有一组宏可以建立自己的可变参数函数,<stdarg.h>
例子
#include <stdio.h>
#include <stdarg.h>

void print_ints(int args, ...)
{
    /*
        保存传给函数的其他参数
    */
    va_list ap;

    /*
        表示可变参数从哪开始
    */
    va_start(ap, args);
    int i;
    /*
        循环遍历所有其他参数,args保存了参数的数目
    */
    for(i=0;i<args;i++) {
        printf("argument:%i\n", va_arg(ap, int));
    }

    va_end(ap);
}

int main()
{
    print_ints(3, 79, 101, 32);
}
坚持原创技术分享,您的支持将鼓励我继续创作!