左右法则 来解析指针问题

来源:互联网 发布:淘宝用户数据分析 编辑:程序博客网 时间:2024/04/27 21:35
首先将“左右法则”的原文搬出来吧:
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.

上面其实已经说得很清楚了,但是刚看这一段时,我还是有很多迷糊的地方。下面我用中文(呵呵,也只能用中文,E文太烂)来讲一讲我的理解。

从最里面开始,也就是从你的变量开始一层一层往外推。最里面那个就是主体,每外面一层都是修饰紧挨着的里面一层的。
所以,你从内向外每看完一层以后,就可以把你看完的都当作一个整体,然后紧挨着的外面这一层就是来修饰这个整体的。
下面的例子中,我上面提到的这个“整体”依次用X1,X2,X3。。。来表示,以便你能看得更清楚,不被迷惑到了。

举例说明吧:

int* a;       /* a是一个指针『*a』,这个指针指向什么?指向int型数据『int X1』。所以,a是一个指向int型数据的指针。*/

int (*a)();     /* a是一个指针『*a』,这个指针指向什么?指向函数『X1()』。这是一个什么样的函数?一个没有参数,返回值为int型的函数『int X1()』。
 所以,a是一个指针,这个指针指向没有参数,返回值为int型的函数*/

int *(a[10]);    /* a是一个有10个元素的数组『a[10]』,数组的元素是什么?这个数组里的元素是指针『*X1』。这个指针指向什么?指向int型数据『int X2』。
所以,a是一个数组,这个数组含有十个元素,每个元素都是指向int型数据的指针*/

int (*a)[10];    /* a是一个指针『*a』,这个指针指向什么?指向有十个元素的数组『X1[10]』。数组的元素是什么?int型数据『int X2』。
所以,a是一个指针,这个指针指向含有十个int型数据的数组。*/

int (*((*a)[10]))(int) /* a是一个指针『*a』,什么样的指针?指向有十个元素的数组的指针『X1[10]』。数组的元素是什么?这个数组的元素是指针『*X2』。指针指向什么?指向函数『X3(int)』。什么样的函数?有一个int型参数,返回值为int型的函数『int X3(int)』。
所以,a是一个指针,这个指针指向有十个元素的数组,每一个元素都是指向"有一个int型参数,返回值为int的函数"的指针。*/

int (*(a[10]))(int (*)()); /* a是一个有十个元素的数组『a[10]』。数组的元素是什么?指针『*X1』。指针指向什么?函数『X2(...)』。什么样的函数?有一个参数,返回值为int的函数。对这个参数分析:这个参数是一个指针『(*)』。指针指向什么?指向函数『Y1()』。什么样的函数?没有参数,返回值为int的函数『int Y1()』。
所以,a是一个有十个元素的数组,数组的元素是指向函数的指针,这些函数的参数为指针,返回值为int。参数的指针是指向"没有参数,返回值为int型的函数"的指针。*/ 

呵呵,晕了吧?我觉得把握住左右法则的要点,按我的理解就是上面提到的:
“从最里面开始,也就是从你的变量开始一层一层往外推。最里面那个就是主体,每外面一层都是修饰紧挨着的里面一层的。
所以,你从内向外每看完一层以后,就可以把你看完的都当作一个整体,然后紧挨着的外面这一层就是来修饰这个整体的。”
百变不离其宗,无论有多复杂,用左右法则层层拨茧抽丝,就可以化繁为简。

上面我的例子中用括号比较多,有些括号还是“多余”的,因为我实在懒得去记C中繁多的优先级与结合性,用括号表示一目了然,也便于别人阅读我的代码。呵呵,我也顺便提醒一下大家,记清这些优先级不错,但是出来卖弄就不对了:)

函数指针我在大学的时候只是听说过,当时不屑一顾,认为这没什么作用,直接调用函数不就可以了?何必那么麻烦?。但是工作以后发现,函数指针实在太有用了。比如说,如果你想在C中秀一秀你的面向对象的技术,那么你可以在用struct来代替class,在struct中用函数指针来代替成员函数。当然函数指针还有许多的用处,呵呵,我才疏学浅,希望以后能深入学习一下写一点这方面的体会。网上有很多资料,很快可以搜索到,你也不必等我的那篇还不知道会不会写的文章到白头:)

好了,咱们继续,现在我们把顺序倒一倒,看看如何用左右法则来根据自己的需要写出确切的申明。

1,一个指向int型数据的指针。
这个so easy: int* a;
但是我要说明一下步骤,因为下面的繁的例子和这个的原理是一样的。
首先抓住要点:这是一个指针,于是我们可以写下 *a。
然后这个指针时指向int型数据,也就是int X1。
然后用 *a替换X1,就变成了 int (*a);
这里因为比较简单,可以去掉括号,变成 int* a;


2,一个有十个指向没有参数返回值为int型的函数的指针的元素的数组。
首先,这是一个数组,有十个元素,我们可以写下:a[10];
去掉对数组的描述,上面的这段话就变成:
“指向没有参数返回值为int型的函数的指针”
我们只抓最外一层:指针。于是变成了:*(a[10])。
去掉对指针的描述,这段话就变成:
“没有参数返回值为int型的函数”
呵呵,这个函数就是 int x();
我们把x用上面的*(a[10])来替代,就变成了:

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


http://hi.baidu.com/himalaya/blog/item/8e262b348599533b5bb5f56b.html

原创粉丝点击