“右左法则”[重要!!!]
The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.
这是一个简单的法则,但能让你准确理解所有的声明。这个法则运用如下:从最内部的括号开始阅读声明,向右看,然后向左看。当你碰到一个括号时就调转阅读的方向。括号内的所有内容都分析完毕就跳出括号的范围。这样继续,直到整个声明都被分析完毕。
对上述“右左法则”做一个小小的修正:当你第一次开始阅读声明的时候,你必须从变量名开始,而不是从最内部的括号。
下面结合例子来演示一下“右左法则”的使用。
int * (* (*fp1) (int) ) [10];
阅读步骤:
1. 从变量名开始 -------------------------------------------- fp1
2. 往右看,什么也没有,碰到了),因此往左看,碰到一个* ------ 一个指针
3. 跳出括号,碰到了(int) ----------------------------------- 一个带一个int参数的函数
4. 向左看,发现一个* --------------------------------------- (函数)返回一个指针
5. 跳出括号,向右看,碰到[10] ------------------------------ 一个10元素的数组
6. 向左看,发现一个* --------------------------------------- 指针
7. 向左看,发现int ----------------------------------------- int类型
1. 从变量名开始 -------------------------------------------- fp1
2. 往右看,什么也没有,碰到了),因此往左看,碰到一个* ------ 一个指针
3. 跳出括号,碰到了(int) ----------------------------------- 一个带一个int参数的函数
4. 向左看,发现一个* --------------------------------------- (函数)返回一个指针
5. 跳出括号,向右看,碰到[10] ------------------------------ 一个10元素的数组
6. 向左看,发现一个* --------------------------------------- 指针
7. 向左看,发现int ----------------------------------------- int类型
总结:fp1被声明成为一个函数的指针,该函数返回指向指针数组的指针.
再来看一个例子:
int *( *( *arr[5])())(); 函数指针数组 该数组的元素指向一个形参为空,返回值为函数指针的函数,返回的函数指针指向一个形参为空返回值为 int * ;
float ( * ( *b()) [] )(); b 函数 形参为空,返回值为数组指针,数组为函数指针数组 指向的函数形参为空,返回值为float.
float ( * ( *b()) [] )(); b 函数 形参为空,返回值为数组指针,数组为函数指针数组 指向的函数形参为空,返回值为float.
void * ( *c) ( char a, int (*b)()); c 函数指针变量 ,指向一个有两个参数的返回值为 void * 的函数,第一个形参为char 第二个形参函数指针,该指针指向一个形参为空,返回值为int的函数。
float ( * ( * e[10]) (int *) ) [5]; 函数指针数组 函数形参为 int * 返回值为数组指针 该数组是一个指针数组,指向float型
float ( * ( * e[10]) (int *) ) [5]; 函数指针数组 函数形参为 int * 返回值为数组指针 该数组是一个指针数组,指向float型