【C语言】函数指针与回调函数
在C语言中:指针是C语言的特色,有着各种各样的指针,普通的变量指针,常量指针,数组指针,指针数组,函数指针,指针函数。我们就讲一下函数指针与回调函数吧
首先关于函数指针,其实很简单。
对于一个函数指针来说,顾名思义,就是一个指向函数的指针,需要知道的是,对于指针而言,他总是存储一块地址,地址里面有着一个,一组,或者一块数据,在函数中,函数的存储是放在代码段的,每个函数都有着一个函数首地址,调用了这个地址相当于调用的这个函数。
具体的可以观看我的这篇博客,其中就通过在内存阶段改变栈帧返回值,成功的调用了一个重启函数。浅谈栈帧(一)
其实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可以将这个声明简化:
typedefint (*ptf) (double*, char);
ptffunction(int );
总结:
其实对于函数指针来说。我们只需要记住。从最中间括号开始往外逐步分析,函数指针是(*)
而指针函数是(*()),懂得会分区,就知道函数指针是什么东西了。弄清楚他本身名字,然后弄清楚他的描述情况。
回调函数:
上面已经说清楚了对于函数指针而言,他有着他自己的名字,有着相对于的描述信息,信息不一样的无法进行赋值配对,然后既然有函数指针这种东西?那么他出现是干什么用的呢?
其实对于函数指针,无非就是让我们在面临不同情况去使用他。函数指针指向不同的情况,来进行不同的操作,在主题函数处理中提供不同的函数指针借口,借此来处理不同的情况。
在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。
来看一个简单例子:
#include<stdio.h>intint_cmp(constvoid*p1,constvoid*p2){if(*(int*)p1>*(int*)p2){return1;}elseif(*(int*)p1==*(int*)p2){return0;}else{return-1;}}void_swap(void*p1,void*p2,intsize){inti=0;for(i=0;i<size;i++){chartmp=*((char*)p1+i);*((char*)p1+i)=*((char*)p2+i);*((char*)p2+i)=tmp;}}voidbubble(void*base,intcount,intsize,int(*cmp)(void*,void*)){inti=0;intj=0;for(i=0;i<count-1;i++){for(j=0;j<count-i-1;j++){if(cmp((char*)base+j*size,(char*)base+(j+1)*size)>0){_swap((char*)base+j*size,(char*)base+(j+1)*size,size);}}}}intmain(){intarr[]={1,3,5,7,9,2,4,6,8,0};//char*arr[]={"aaaa","dddd","cccc","bbbb"};inti=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");return0;}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。