一、函数指针
下面声明了一个函数指针,第一次看到这种声明是很迷惑的,但只要根据C语言运算符优先级,理解这种声明就比较顺利成章了,
void (*foo)();//声明了一个函数指针
括号让这个声明变成了一个函数指针,*表示这是个指针,下图说明了函数指针声明的各个部分

foo是一个函数指针变量,*foo就是该指针指向的函数,进而(*foo)()就是调用这个函数的方式,在上面这个函数声明中,*foo两侧的括号非常重要,()的优先级高于单目运算符*,没有括号的话,*foo与*(foo())的含义完全一致。变量的指针指向的是一块数据,而指针指向不同的变量,则取出来的就是不同的数据,而对于函数指针而言,它指向的是函数经过编译后的起始地址,也称之为入口地址,指针指向不同的函数,则具有不同的行为。在一般的情况中,我们直接使用函数名来完成对函数的调用,函数出现在表达式中时,编译器会将其转换为一个指针,也就是说函数名直接对应了函数生成的指令代码在内存中的位置,因此,可以使用同一个函数指针指向不同的函数。
二、返回指针的函数
指针变量除了可以作为函数的类型参数外,还可以作为函数的返回值,这就是返回指针的函数(部分文档也称之为指针函数),事实上,返回指针是很容易的,只要返回的数据类型的指针即可,例如
int *max(int *p1,int *p2)
{
if(*p1>p2)
return p1;
else
return p2;
}
从函数返回指针时,一般可分为两种情况
1、使用malloc在函数内部分配内存并返回其地址,调用者复杂释放返回的内存
2、传递对象给函数并供函数使用,这样内存的释放都是调用者的责任。
可以看出,从函数返回指针时可能存在隐患,如:
- 返回为初始化的指针
- 返回指向无效地址的指针
- 范围局部变量的指针(内存可能被别的帧栈覆写)
- 返回指针但没有释放内存
三、函数指针与返回指针的函数的区别。
之前谈到 ,括号的位置不同,其具体的含义不同,如
int *pf(int *, int); // int *(int *, int) 这个函数返回一个指针 int (*pf)(int, int); // int (*)(int, int)这是一个指向函数指针
两者之间只差一个括号,但含义完全不同,函数指针本质是一个指针变量,其指向的是一个函数。指针函数本质是一个函数,其返回值是一个指针。判断两者区别主要是靠运算符优先级,括号的优先级比*优先级要高,对于第一个函数声明,pf先与(int *,int)结合,再与int *结合 ,因此是一个指针函数,对于第二个函数声明,由于加了括号,pf先与*结合,再与(int *,int)结合,因此是一个函数指针。
浙公网安备 33010602011771号