目录
5、以下两个指针能分析清楚的话,那么 99% 的 C 语言指针问题都难不住你。
0、摘要
指针函数是返回指针的函数,函数指针是指向函数的指针。
int* FunctionReturnsPtr(int a); //返回值为指向int型的指针
将函数原型的函数名改为指针名,再在指针名前加星星,加括号,即可得指向该原型的函数指针。
想指向的函数原型: int FunctionA(double);
则指向该原型的函数指针PointerOfFunctionA定义为:int (*PtrrOfFunctionA)(double);
1、指针函数
返回指针的函数。
//定义一个返回值为“指向int型的指针”类型的函数
int* FunctionReturnsPtr(void) {
int* ptr = NULL;
return ptr;
}
2、函数指针
指向函数的指针。函数的外号。
常用于做回调函数,或者作为某平台的移植接口出现。
// 定义一个返回值为int型,传入参数为int型的函数。
int FunctionA(int a) {
printf("%d\n",a);
return 0;
}
// 定义一个返回值为int型,传入参数为int型的函数指针。
int (*PtrOfFunctionA)(int);
// 测试函数,通过该函数指针调用该函数
void TestPtrOfFunctionA(void) {
//将函数首地址赋值给函数指针的方法一
PtrOfFunctionA = FunctionA;
//将函数首地址赋值给函数指针的方法二
PtrOfFunctionA = &FunctionA;
(*PtrOfFunctionA)(1);//通过函数指针调用函数,此处等价于FunctionA(1);
PtrOfFunctionA(2); //在古老的编译器上不能这么用,此处等价于FunctionA(2);
FunctionA(3);
}
打个比方:使用函数指针相当于给同一个函数取外号。比如有个函数,名为A,我们又定义了指向这个跟A拥有同类型返回值、同类型传参的函数指针Ptr1、Ptr2、Ptr3,将A赋值给Ptr1、Ptr2、Ptr3,则此时,该函数就有了1个本名+3个外号,共4种喊法,无论用哪个名字或外号喊它/调用它,效果都是一样的。就是喊外号的时候外号前面要带个星星*。
3、函数指针数组
指向函数的指针的数组,即一堆指针。
// 定义一个返回值为int型,传入参数为int型的函数。
int FunctionOne(int a) {
printf("1 %d\n",a);
return 0;
}
// 定义一个返回值为int型,传入参数为int型的函数。
int FunctionTwo(int a) {
printf("2 %d\n",a);
return 0;
}
//定义一个返回值为int型,传入参数为int型,容量为2的函数指针数组。
int (*PtrOfFunctionXArray[2])(int) = {FunctionOne, FunctionTwo};
//测试函数,调用函数指针数组等价于调用原函数
void TestPtrOfFunctionArray(void){
(*PtrOfFunctionXArray[0])(1);
(*PtrOfFunctionXArray[1])(2);
}
4、将函数作为传参传入另一个函数
#include <iostream>
int add(int a, int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
void func(int e, int d, int(*f)(int a, int b)){
// 传入了一个int型,双参数,返回值为int的函数
std::cout<<f(e,d)<<std::endl;
}
int main()
{
func(2,3,add);
func(2,3,sub);
return 0;
}
5、以下两个指针能分析清楚的话,那么 99% 的 C 语言指针问题都难不住你。
char *(* c[10])(int **p);
int (*(*(*pfunc)(int *))[5])(int *);
分析如下:
char *(* c[10])(int **p);
step1: (* c[10]):一个容量为10的指针数组,
step2: c的*的括号外面是(指向了)"char *()(int **p)"
step3: 即为函数指针,指向的函数原型为:char *Function(int **);
step4: 串起来:定义了一个容量为10的函数指针数组,指向的函数原型为char *Function(int **);
int (*(*(*pfunc)(int *))[5])(int *);
step1:
(*(*pfunc)(int *)):
pfunc是一个指针,pfunc的*的括号外面是(指向了)"*()(int*)",
即为函数指针,指向的函数原型为:?* Function(int*),
返回值为*,即指针,指针指向的数据类型未知
step2:
*(*(*pfunc)(int *))[5]:
返回值的*指向了"*()[5]",
说明返回值指向的数据类型为容量为5的指针数组,
该指针数组指向的数据类型未知
step3:
int (*(*(*pfunc)(int *))[5])(int *):指针数组的*的括号外面是"int ()(int *)",
即为函数指针数组,指向的函数原型为:int Function(int*)
串起来:
pfunc是一个函数指针,指向函数原型的传参为int*,
函数的返回值为指针,指向一个容量为5的指针数组,
指针数组种的指针的指向原型为int Function(int*)的函数,
参考:
深入浅出——理解c/c++函数指针 - 知乎 (zhihu.com)