【C语言】函数指针与回调函数-创新互联

在C语言中:指针是C语言的特色,有着各种各样的指针,普通的变量指针,常量指针,数组指针,指针数组,函数指针,指针函数。我们就讲一下函数指针与回调函数吧

我们提供的服务有:做网站、网站建设、微信公众号开发、网站优化、网站认证、沁县ssl等。为上千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的沁县网站制作公司

首先关于函数指针,其实很简单。

    对于一个函数指针来说,顾名思义,就是一个指向函数的指针,需要知道的是,对于指针而言,他总是存储一块地址,地址里面有着一个,一组,或者一块数据,在函数中,函数的存储是放在代码段的,每个函数都有着一个函数首地址,调用了这个地址相当于调用的这个函数。

    具体的可以观看我的这篇博客,其中就通过在内存阶段改变栈帧返回值,成功的调用了一个重启函数。浅谈栈帧(一)

    其实C++特性中的虚函数表就有利用这一点。

    所以说呢,函数指针就是一个指向函数首地址的指针,好了,先了解这个定义,然后我们进入下一个阶段。

对于指针,他不仅仅要指向一个具体的量,他还需要其他的标识符来描述这个量的具体属性。

 例如:char* str,void *func(int,int);

在指针符号*的左右,都是在描述这个指针的具体信息。

那么对于函数指针而言,这是怎么样的呢。

    void (*f) ( );虽然()的优先级高于*,但由于有括号存在,首先执行的是解引用,所以f是一个指针;接下来执行( ),表明f指向一个函数,这个函数不返回任何值。现在得出结论:f是一个指向不接受参数且不返回任何值的函数的指针,简称函数指针(pointer to function)。

<1>.初始化

注意指向函数的指针(函数指针)指向的是函数而非普通的变量,它所指向的函数也是有特定类型的,函数的类型由它的返回值类型以及形参列表确定,和函数名无关。对函数指针初始化时可以采用相同类型函数的函数名或函数指针(当然还有零指针常量)。假如有函数void test ( ),int wrong_match (int)和函数指针void (*ptf) ( )。

下面的初始化是错误的,因为函数指针的类型与函数的类型不匹配:

f = wrong_match;

f = & wrong_match;

ptf = wrong_match;

ptf = & wrong_match;

以下初始化及赋值是合法的:

f = test;

f = &test;

ptf = test;

ptf = &test;

f = pf;

要做出解释的是test和&test都可以用来初始化函数指针。C语言规定函数名会被转换为指向这个函数的指针,除非这个函数名作为& 操作符或sizeof操作符的操作数(注意:函数名用于sizeof的操作数是非法的)。也就是说f = test;中test被自动转换为&test,而f= &test;中已经显示使用了&test,所以test就不会再发生转换了。因此直接引用函数名等效于在函数名上应用 & 运算符,两种方法都会得到指向该函数的指针。

int (*function(int)) (double*,char);要了解此声明的含义,首先来看function(int),将function声明为一个函数,它带有一个int型的形式参数,这个函数的返回值为一个指针,正是我们本将开头讲过的函数指针int (*) (double*, char);这个指针指向一个函数,此函数返回int型并带有两个分别是double*型和char型的形参。如果使用typedef可以将这个声明简化:

typedef int (*ptf) (double*, char);

ptf function(int );

总结:

    其实对于函数指针来说。我们只需要记住。从最中间括号开始往外逐步分析,函数指针是(*)

而指针函数是(*()),懂得会分区,就知道函数指针是什么东西了。弄清楚他本身名字,然后弄清楚他的描述情况。

回调函数:

    上面已经说清楚了对于函数指针而言,他有着他自己的名字,有着相对于的描述信息,信息不一样的无法进行赋值配对,然后既然有函数指针这种东西?那么他出现是干什么用的呢?

    其实对于函数指针,无非就是让我们在面临不同情况去使用他。函数指针指向不同的情况,来进行不同的操作,在主题函数处理中提供不同的函数指针借口,借此来处理不同的情况。

    在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。

    来看一个简单例子:

#include 

int int_cmp(const void * p1, const void * p2)
{
    if (*( int *)p1 > *(int *) p2)
    {
        return 1;
    }
    else if (*( int *)p1 == *(int *) p2)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

void _swap(void *p1, void * p2, int size)
{
    int i = 0;
    for (i = 0; i< size; i++)
    {
        char tmp = *((char *)p1 + i);
       *(( char *)p1 + i) = *((char *) p2 + i);
       *(( char *)p2 + i) = tmp;
    }
}
void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
    int i = 0;
    int j = 0;
    for (i = 0; i< count - 1; i++)
    {
        for (j = 0; j 0)
           {
               _swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);
           }
       }
    }
}
int main()
{
    int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
    //char *arr[] = {"aaaa","dddd","cccc","bbbb"};
    int i = 0;
    bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
    for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
    {
       printf( "%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网站标题:【C语言】函数指针与回调函数-创新互联
网站网址:http://myzitong.com/article/disggh.html