理解复杂声明的简单方法

code_tin 2006-04-30 11:56:27
关于C/C++那可怕声明的理解方法已经有许多种
大多都是通过向右再向左再向右之类的分析方法
最后左右左右的搞得许多初学者可能还是搞不清楚
今天我要说的方法当然也需要剥洋葱一样的层层分析
但是大家会稍微轻松一点
同时也有些小技巧在里面

其实声明的分析同样是通过运算符的优先级表来的
许多声明分析方法都把声明分析独立的提取出来
其实这样是不对的
从根本上来说。理解了运算符的优先级次序就完全足够了,你不用再去学习什么声明的分析方法
但是优先级一共16级,实在太复杂了
下面我说的就是通过简化优先级表来简化你理解声明的方法
优先级表的第一层是
() [] -> .
这一层严格来说不算是运算符
其实大家看() []
就知道了,外面许多声明分析方法第一步就是从表达式中的变量往右看
为什么往右看
因为优先级最高的这部分东西都是在表达式的右边的
(),函数声明,[]数组声明,->和.取成员
都是在右边的,他们优先级最高,所以其他分析方法都是按照方向来的
你们可以抛弃右左右左这样的模式
记住第一层优先级的就是在表达式右边的.
int a();是什么?简单.a是一个函数().返回int
int a[][];
a是一个数组
数组里面又是一个数组
所以a是一个二维数组,简单了吧;
那么int (* a[])();是什么?
a是一个数组->指针数组->函数指针数组
这里碰到了指针,先不用慌,看不懂没关系,接下去看完你就会懂了

第二个优先级的运算符
++ -- ! ~ & * sizeof (type)强制转换
这层的东西有些多
主要记住++ -- ! & 在这一层就够了
第二层就是我们说的单目运算符
就是只要一个变量就可以进行运算了
比如a++

这里不要记住*
我们把*放在下一层.
第三层开始是双目运算
需要两个变量比如a*b
第三层是
* / %
第四层是
+ -
先乘除后加减
把*放到第三层去理解是为了方面理解
*a++这样的声明
因为*和++都是第二层,很难理解
而取值操作*和乘法操作的*都是一个符号
我们可以理解成编译器比较笨,不能区分*的含义
而乘,除在一层里面。所以在第三层(当然实际上编译器比我们想象的要聪明的多,这里只是为了方便记忆)

这样*a++就很好区分了
++的优先级高于*
那么结果就是a先++,然后取a的值
这里要记住因为++不对变量本身做立即的变更,所以*取值出来的是原来的a值,而不是++后的.

后面的十几种优先级可以先不用怎么背
因为大部分情况下面不会有歧异,对于声明分析也没有太大作用.
等慢慢深入以后再背熟吧

这样我们看前面一个声明
int (* a[])()
先是a,这个是表达式
a附近最高优先级就是[]
a[],说明a是一个数组
* a[]
说明这个数组里面放指针
(* a[])()
前面一个算一个整个部分,后面加了(),说明是函数
最后前面的int说明函数的返回值是int
连起来就是a是一个包含指向返回值是int的函数的指针的数组

*注:因为分析方便我把数组大小去掉了,上面的正确形式应该如下
int (* a[5])();

我们再来看比较容易搞起来的声明
(* a)()
以及
(* a())()

(* a)()
a是一个指针
右边括号说明了是一个函数指针.

(* a())()
首先离a最高优先级的是()
因为我们把*的优先级移动到下面一层去了
a是一个函数
然后是*
函数前面的就是返回值
说明a()返回一个指针
指针(*)()
说明是一个函数指针
最后a是一个函数,返回一个函数指针


最后说一下,如果能完整背出运算符优先级表
就能很轻松的理解函数声明
如果不能背全,那么背出我上面说的4层基本够了
注意把*理解成乘法的优先级,就容易了.
碰到实在太复杂的问题
就直接放到CSDN来散分就行了:D
...全文
169 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
code_tin 2006-05-07
  • 打赏
  • 举报
回复
其实再复杂的也就这样分析了
主要就是耐心和细心的问题了
还有一点
碰到[]读成数组,碰到()读成函数
可能看起来很简单.不过很有效
比如函数指针不用死记它的形式
void (* f)(int p);
* f : f是一个指针,指针指向什么呢?
后面是(int p) : 碰到()说明这个是个函数,那么指针就指向这个函数,函数里面有个参数是int
void :函数返回void空
最后f是指针,指针指向函数,函数有一个int参数,返回void
这样一步一步过来,再复杂的声明也只是细心的问题而已.
abayforever 2006-05-07
  • 打赏
  • 举报
回复
遇到更复杂的,可以看看Expert C。
LoveCreatesBeauty 2006-05-06
  • 打赏
  • 举报
回复
bullshit
caiyujie87 2006-05-06
  • 打赏
  • 举报
回复
up up up up up
code_tin 2006-05-02
  • 打赏
  • 举报
回复
被楼上认出来了?呵呵。是的。
woaibobo 2006-05-02
  • 打赏
  • 举报
回复
强人就是强!!
这样的帖咋都的顶!!
lk_517 2006-05-01
  • 打赏
  • 举报
回复
好文章

楼主是不失邪恶八进制的?
lengsehuoyan 2006-05-01
  • 打赏
  • 举报
回复
支持一下

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧