右左法则:
法则论述:从变量名看起,先往右,再往左,碰到圆括号就调转阅读的方向;括号内分析完就跳出括号,还是先右后左的顺序。如此循环,直到分析完整个定义。
一般来说结合的规律有以下几条:
typedef (*var)(...); // 变量名var与*结合,被圆括号括起来,右边是参数列表。表明这是函数指针
typedef (*var)[]; //变量名var与*结合,被圆括号括起来,右边是[]运算符。表示这是数组指针
typedef (*var[])...;// 变量名var先与[]结合,说明这是一个数组(至于数组包含的是什么,由旁边的修饰决定)
注意一下第二第三条;
由于
[
]
[]
[]的优先级大于
∗
*
∗,因此*var[]
优先被认为是内容是指针的数组;
但是值得注意的是,对于嵌套情况下,对于指针的详细内容,会在括号外进行补全;
类似于,括号外面是针对于前者缺失的详细类型的一种补全;
详细例子:
例如:
float (* (*fp2) (int, int, float)) (int);
首先关注变量名,fp2;
从右看,右括号,所以向左看,得到*fp2,说明,fp2是一个指针;
跳出上层括号,向右看发现有括号,所以只能是函数参数列表,则说明*fp2为一个函数指针;
向左看,发现(*fp2)
左边为*,说明返回值为一个指针,本层括号判断结束;
从(*(*fp2)(int,int,float))
,外层开始,描述返回值指针应该是什么的类型;
向右看,为一个参数列表,说明返回的指针为一个函数指针,参数列表为int,返回值为float;
因此fp2为一个函数指针,指向一个形参为(int,int,float)
,返回值也为一个函数指针,形式形参为int,返回值为float;
例如:
double (* (* (*fp3) ()) [10]) ();
首先关注fp3;
从右看,直接括,前有*,说明返回的是一个指针,本层结束;
下层括号描述上层的指针类型,右看为一个括号,说明该指针为函数指针,形参为空,返回为一个指针*(*fp3)()
;
下层括号描述上层指针的类型,向右看为 [ ] [] [],则说明返回的是一个指向数组的指针,向左看为*,说明指针的内容物为指针;
下层括号描述上层数组内指针的类型,向右看为括号,所以为函数指针,且返回值为double;
因此,fp3为一个指向函数的指针,且函数无参数,该函数返回一个指向数组的指针,数组内容也为函数指针,且不接受参数,返回double;