入门阶段,看见类似void * (*(*fp1)(int))[10];的复杂声明,晕乎。直接略过,这种复杂的东东,不应该是入门者需要去学习的知识。
进阶阶段,这种知识就必需得搞得清清楚楚了,不然还等到高阶阶段才学习这个么?
现在,就来带大家了解一下,这类复杂的声明怎么解?
在解之前,先看一个入门的知识点,指针函数作为参数传递。
int func_call(string text) {
cout << text << endl;
return 5;
}
void func_pointer(int (*fp)(string)) {
cout << fp("func_pointer") << endl;
}
void main() {
int (*fp)(string);//声明函数指针,此函数接受一个字符串参数并返回一个整型
fp = func_call;
func_pointer(fp);//将函数指针作为参数传递
}
怎么声明函数指针相信大家都很清楚,现在就来解复杂声明
1. void * (*(*fp1)(int))[10];
2. float (*(*fp2)(int,int,float))(int);
解1:void * (*(*fp1)(int))[10];
(1)包含fp1的最内层小括号是(*fp1):fp1是指针(2)往(*fp1)右边看是(int),右边是小括号即是函数:指向带有一个int型参数的函数
(3)再往(*fp1)左边看是*,当右边是函数,左边即是函数的返回值:且函数返回一个指针
(4)往(*(*fp1)(int))右边看是[10],右边中括号表示数组:指针指向一个大小为10的数组
(5)再往(*(*fp1)(int))左边看是void *,即是数组的类型:数组类型为void *
好了,把整段话拼出来吧:
fp1是指针,指向带有一个int型参数的函数,且函数返回一个指针,指针指向一个大小为10的数组,数组类型为void *
解2:float (*(*fp2)(int,int,float))(int);
(1)包含fp2的最内层小括号是(*fp2):fp2是指针
(2)往(*fp2)右边看是(int,int,float),右边是小括号即是函数:指向带有3个参数的函数
(3)再往(*fp2)左边看是*,当右边是函数,左边即是函数的返回值:且函数返回一个指针
(4)往(*(*fp2)(int,int,float))右边看是(int),右边小括号表示函数:指针指向带1个整型参数的函数
(5)再往(*(*fp2)(int,int,float))左边看是float,即是函数的返回值:函数返回float
把整段话拼出来:
fp2是指针,指向带有3个参数的函数,且函数返回一个指针,指针指向带1个整型参数的函数,函数返回float
任何复杂的声明都按此方法解,中间的变量名开始,右--左--右--左。编译器也是按此步骤读声明的。
下面代码示例:
typedef void* (*AP)[10];
AP func_fp1(int i) {
cout<< "func_fp1:" << i << endl;
AP a = nullptr;
return a;
}
void main() {
void * (*(*fp1)(int))[10];
fp1 = func_fp1;
(*fp1)(5);
}
声明也使用类型定义会使声明看起来更简单一点
void main() {
AP (*fp1)(int);
fp1 = func_fp1;
(*fp1)(5);
}
float func_f(int i) {
cout<< "func_f:" << i << endl;
return 1.0f;
}
typedef float (*FP)(int);
FP func_fp2(int i,int j,float f) {
cout<< "func_fp2 i:" << i << ", j:" << j << ", f:" << f << endl;
//float (*fp)(int);
FP fp;
fp = func_f;
return fp;
}
void main() {
float (*(*fp2)(int,int,float))(int);
fp2 = func_fp2;
(*(*fp2)(1,2,3))(4);
}
一样可以用类型定义
void main() {
FP (*fp3)(int,int,float);
fp3 = func_fp2;
(*(*fp3)(5,6,7))(8);
}