C语言

C5. 函数指针的实例讲解(上)

2020-07-11  本文已影响0人  开源519

1.函数指针概念
函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数
以上的概念是参考百度百度百科来的,简单的讲就是指向函数的指针。

2.用途
通过以上的概念可以明确,指针函数的用途是调用函数和做函数的参数。
Talk is cheap, show me the code!从这两个用途举例说明:
2.1调用函数
首先看到以下例子,利用函数指针实现一个简单的调度:

#include <stdio.h>

#define TASK_NUM sizeof(scheduler)/sizeof(struct task_schedule)

struct task_schedule
{
    int num;
    int (*func)(int);
};

int task1(int num)
{
    printf("%s: %d!\n", __func__, num);
    return 0;
}

int task2(int num)
{
    printf("%s: %d!\n", __func__, num);
    return 0;
}

int main()
{
    int i = 0;
    struct task_schedule scheduler[] = {
        {0, task1},
        {1, task2},
    };
    
    for(i = 0; i < TASK_NUM; i++){
        scheduler[i].func(1);
        printf("\n");
    }

    return 0;
}

以上例子的功能是遍历执行数组scheduler中所有的func函数,数组schedule是一个struct task_schedule类型的结构体, task_schedule结构体中func的定义就是运用了函数指针。在代码中将schedule的func成员指向实例的task1,task2函数入口,直接遍历即可执行task1,task2函数。

运行结果:

输出.png

2.2做函数参数
这里是将2.1代码中数组的赋值重新封装了一个接口:

#include <stdio.h>

typedef int (*PTASK)(int);
#define TASK_NUM sizeof(scheduler_list)/sizeof(struct task_schedule)

int task1(int num)
{
    printf("%s: %d!\n", __func__, num);
    return 0;
}

int task2(int num)
{
    printf("%s: %d!\n", __func__, num);
    return 0;
}

struct task_schedule
{
    int num;
    PTASK func;
    //int (*func)(int);
};

void scheduler(struct task_schedule *sheduler, PTASK *task, int len)
{
    int j = 0;
    struct task_schedule *p;
    
    p = sheduler;
    for(; j < len; j++) {
        p->num = j;
        p->func = task[j];
        p++;
    } 
}

int main()
{
    int i = 0;
    struct task_schedule scheduler_list[2];
    PTASK task_all[] = {task1, task2};

    scheduler(scheduler_list, task_all, 2);
    for(i = 0; i < TASK_NUM; i++){
        scheduler_list[i].func(1);
        printf("\n");
    }
    
    return 0;
}

scheduler(struct task_schedule *sheduler, PTASK *task, int len)函数就是将PTASK函数指针作为参数,从而在此函数中填充sheduler数组,然后遍历。当函数指针作为参数时,这里用了typedef将函数指针重新声明,通过比较前后代码可以看出区别,下次也会讲一下typedef与函数指针搭配使用的原理。

输出结果:


输出.png

个人总结,转载请标明出处及链接,谢谢!

上一篇 下一篇

猜你喜欢

热点阅读