C语言中的函数指针
函数指针是C语言的灵魂之一,基于C语言实现的面向对象,底层都以函数指针为基础。
函数指针的定义
C语言中,可以通过以下方式定义函数指针:
type (*fn)(args)
其中,fn
为指针变量名,type
为指针所指向的函数的返回值类型,args
为指针所指向的函数的参数列表。可以通过&
运算符对函数指针赋值,通过(*fn)()
的方式调用。举例:
int (*fn)(int a);
int func(int a) {
printf("call func, arg a = %d\n", a);
return a;
}
int main(int argc, char **argv) {
fn = &func;
(*fn)(10);
return 0;
}
参数和返回值类型共同决定函数指针的类型,不同类型的函数指针之间不能做类型转换。
函数指针数组
指针数组
int *p[10];
在这条C语言语句中,由于[]
运算符的优先级高于*
运算符,因此p是一个有10个元素的数组,再结合*
,可知数组p中的每一个元素的类型都是int型指针。上述声明等价于:
int *(p[10]);
数组指针
int (*p)[10];
在这条C语言语句中,首先,p是一个指针,接着,p是一个指向数组的指针,并且数组中每一个元素的类型都是int。
函数指针数组
函数指针数组的定义同普通指针数组的定义相同。
int (*fn[10])(args);
这样就定义了一个有10个元素的指针数组,其中,每个指针都是一个函数指针,指向一个返回值类型为 int,参数为 args 的函数。
返回指针的函数
C语言中,可以将函数的返回值类型定义为指针,具体做法例如:
int * (*fn)(args);
这样便定义了一个返回值类型为int型指针,参数为args的函数指针。
返回数组指针的函数
C语言中,函数的返回值类型可以是指向数组的指针。例如:
int (*fn(args))[];
int (*fu(args))[] {
}
这样,fn
便是一个返回数组指针的函数,该数组指针指向一个有5个int型元素的数组。
复杂指针嵌套语句的解读
C语言中所有复杂的指针声明都是由各种声明嵌套构成的。左右法则是一个从C标准中归纳出来的解读复杂指针声明的方法。
左右法则:首先从最里面的未定义标识符开始,然后往右看,再往左看。每当遇到圆括号时,就掉转阅读方向。一旦解析玩圆括号里面所有的内容,就跳出圆括号。重复这一过程直至整个声明解析完毕。
举例:
int (*(*func)(int *p))[5];
首先,func是一个函数指针,指向一个参数为int *p
的函数,函数的返回值类型为指向数组的指针,该数组具有5个int型的元素。
再如下例:
int (*(*fn)(args))[5];
这便定义了一个函数指针,指向的函数返回一个数组指针,该数组指针指向一个有5个int类型的元素的数组。
typedef与函数指针
在C语言中,typedef用作类型定义。建立一个类型别名的方法如下:
在传统的变量声明表达式中用类型名替代变量名,然后把
typedef
关键字加在该语句的开头。
例如:
typedef int* (*A[5])(int, char **);
A a[5];
与
int* (*a[5])(int, char **);
是等价的。
其他的更简单的使用typedef的语句如:
typedef long long ll;
typedef char * pchar;
也就容易理解了。
函数指针作为参数
将函数指针类型作为参数进行传参时,函数名前加不加&
符号都可以。