右左法则

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.

这是一个简单的法则,但能让你准确理解所有的声明。这个法则运 用如下:从最内部的括号开始阅读声明,向右看,然后向左看。当你碰到一个括号时就调转阅读的方向。括号内的所有内容都分析完毕就跳出括号的范围。这样继 续,直到整个声明都被分析完毕。对上述 右左法则 做一个小小的修正:当你第一次开始阅读声明的时候,你必须从变 量名开始,而不是从最内部的括号。

 

#include<signal.h>

void (* signal (int signo, void (*func) (int) )) (int );

 

signal 函数,阅读步骤:

  1. func 开始 -----------------------------------------------func
  2. 向右看碰到)因此向左看碰到一个 *-------------------------- 一个指针
  3. 跳出括号,碰到( int --------------------------------------------------------- 一个带一个 int 类型参数的函数
  4. 向左看, int signo ------------------------------------------------------------ 又一个 int 类型的参数
  5. 红色部分处理完跳出括号向右看遇到)向左遇到 *-------------------- signal 函数)返回一个指针
  6. 粗体部分看完了跳出向右遇到( int -------------------------------------- 一个带 int 类型参数的函数
  7. 向左看发现 void-------------------------------------------------------------------void 类型, signal 函数返回的指针指向一个参数为 int 类型,返回值为 void 类型的函数。

 

可以理解为 signal 函数的参数有两个,一个是 int 类型,一个是一个函数指针(参数类型为 int ,返回值为 void ),返回值为一个函数指针(参数类型为 int ,返回值为 void )。

因此按照书中的解释,如果使用 typedef 更好理解一些:

typedef  void SigFunc ( int );   // 声明一个类型,该类型为函数且有一个 int 参数并且返回值为 void 型。

signal 函数可以简写为:

SigFunc * signal int SigFunc* );

 

关于理解复杂的 c++ 声明,这上面的左右法则是从 http://buaadallas.blog.51cto.com/399160/80947 学来的,上面有几个更复杂的声明:

下面结合例子来演示一下 右左法则 的使用。

int * (* (*fp1) (int) ) [10];

阅读步骤:
1.
从变量名开始 -------------------------------------------- fp1
2.
往右看,什么也没有,碰到了 ) ,因此往左看,碰到一个 * ------ 一个指针
3.
跳出括号,碰到了 (int) ----------------------------------- 一个带一个 int 参数的函数
4.
向左看,发现一个 * --------------------------------------- (函数)返回一个指针
5.
跳出括号,向右看,碰到 [10] ------------------------------ 一个 10 元素的数组
6.
向左看,发现一个 * --------------------------------------- 指针
7.
向左看,发现 int ----------------------------------------- int 类型


总结: fp1 被声明成为一个函数的指针 , 该函数返回指向指针数组的指针 .


再来看一个例子:

int *( *( *arr[5])())();

阅读步骤:
1.
从变量名开始 -------------------------------------------- arr
2.
往右看,发现是一个数组 ---------------------------------- 一个 5 元素的数组
3.
向左看,发现一个 * --------------------------------------- 指针
4.
跳出括号,向右看,发现 () -------------------------------- 不带参数的函数
5.
向左看,碰到 * ------------------------------------------- (函数)返回一个指针
6.
跳出括号,向右发现 () ------------------------------------ 不带参数的函数
7.
向左,发现 * --------------------------------------------- (函数)返回一个指针
8.
继续向左,发现 int --------------------------------------- int 类型

//arr is an array of 5 pointers to functions
//that take no arguments and return pointers to
//functions having no arguments and having int type as return value.

还有更多的例子:

float ( * ( *b()) [] )();     // b is a function that returns a
            // pointer to an array of pointers
            // to functions returning floats.

void * ( *c) ( char, int (*)());   // c is a pointer to a function that takes
            // two parameters:
            //   a char and a pointer to a
            //   function that takes no
            //   parameters and returns
            //   an int
            // and returns a pointer to void.

void ** (*d) (int &, char **(*)(char *, char **));   // d is a pointer to a function that takes
            // two parameters:
            //   a reference to an int and a pointer
            //   to a function that takes two parameters:
            //   a pointer to a char and a pointer
            //   to a pointer to a char
            //   and returns a pointer to a pointer
            //   to a char
            // and returns a pointer to a pointer to void

float ( * ( * e[10]) (int &) ) [5];      

            // e is an array of 10 pointers to
            // functions that take a single
            // reference to an int as an argument
            // and return pointers to
            // an array of 5 floats.

你可能感兴趣的:(C++,c,C#,Blog,Go)