C语言优先级
wubingqp2012/10/24软件综合 IP:广东
0. 为什么要掌握优先级
1. 优先级
1.1 优先级图表
1.2 运算符实例
1.3 优先级顺口溜
2. 结合性
3. 参考资料

    写代码的时候,常会翻看的一个表就是“c语言运算符优先级表”。c的运算符优先级常常很让人头疼。

0. 为什么要掌握优先级

    想想这两个问题:
        a. 读别人的代码,遇到优先级问题看不懂,怎么办?
        b. 一堆的括号,美观吗?
        本想贴一张画来装饰墙壁,却用了一堆纸来固定!
        有人说代码写多了,自然就会了。这个是很宽泛的说法。看你写的代码的水准,有些东西可能你一直都接触不到,何谈熟练。有些东西一定要梳理,总结。

1. 优先级

1.1 优先级图表

[upload=2]

    优先级最高者不是真正意义上的运算符,包括:数组下标,函数调用,结构体成员选择符。
    单目运算符的优先级次之。(! ~ ++ -- - (type) * & sizeof)
    然后是双目运算符。双目运算符里, 算数运算符(* / % + -)优先级最高, 移位(<< >>)次之, 关系运算符(< <= > >= != ==)再次之, 接着是位运算符(& ^ | ),逻辑运算符(&& ||) 条件运算符(?: 三目),赋值运算符(= ...)。
    任何一个逻辑运算符的优先级低于任何一个关系运算符。
    移位运算符的优先级比算数运算符要低,但是比关系运算符要高。

1.2 运算符实例
    a. while (c = getc(in) != EOF)
        putc(c, out)
        循环的意思是复制一个文件到另一个文件。但是由于!=的优先级比赋值运算符的优先级高,所以c被赋予了getc()的返回值与EOF比较后的布尔值,结果向out中写入了一堆1.
    b. 解释下面几个声明
    char *p[];
    char (*p)[];
    int *fp();
    int (*fp)();

    char *p[]
        常常被错误的理解为指向字符数组的指针。
        正确的是p一个数组,里面元素是指向字符的指针类型。
    char (*p)[]
        p是指向指向字符数组的指针。
    int *fp()
        常常错误理解为函数指针,该函数返回int类型。
        正确的是fp是一个函数,他返回一个执行int的指针。
    int (*fp)()
        fp是函数指针,该函数返回int类型。
    
    c. 解释下面的表达式
    *p.f;
    val & mask != 0;
    max = val1 > val2 ? val1 : val2;

    *p.f
        对p去f偏移,作为指针,然后进行解引用。相当与*(p.f),因为.的优先级高与*。比较(*p).f。
    val & mask != 0
        相当与val & (mask != 0).
    max = val1 > val2 ? val1 : val2
        相当与 max = (val1 > val2 ? val1 :val2).
    
    d. 一个复杂的声明

    char *(* c[10])(int **p);
    1. 有两个小括号,小括号的结合行是自左向右,所以我们先关注第一个小括号,简化声明(*c[10])();
        c是一个数组,里面放10指针,后面紧跟这一个括号,所以这些指针是函数指针。
    2. 关注第二个括号,(int **p)
        显然p是函数的参数,它是个指向指针的指针。
    3. 这看最前面的*
        char *说明该函数的返回值是一个指向字符的指针。
    4. 这个声明的意思就是:c是一个数组,里面有10个函数指针,指向的函数返回指针,指向字符,函数的参数是指向int类型指针的指针。

1.3 优先级顺口溜
    醋坛酸味灌
    味落跳福豆

    共44个运算符

    醋-初等,4个: ( ) [ ] -> 指向结构体成员 . 结构体成员
    坛-单目,9个: ! ~ ++ -- -负号 (类型) *指针 &取地址 sizeof长度
    酸-算术,5个: * / % + -减
    味-位移,2个: << >>
    灌-关系,6个: < <= > >= == 等于 != 不等于
    味-位逻,3个: & 按位与 ^ 按位异或 | 按位或
    落-逻辑,2个: && 逻辑与 || 逻辑或
    跳-条件,1个,三目: ? :
    福-赋值,11个: = += -= *= /= %= >>= <<= &= ^= |=
    豆-逗号,1个: ,

    我更推荐在原理上理解以及长时间的使用来掌握,这顺口溜是网上刚刚翻到的,觉得挺好,辅助记忆。

2. 结合性
    在标准C语言的文档里,对操作符的结合性并没有作出非常清楚的解释。一个满分的回答是:它是仲裁者,在几个操作符具有相同的优先级时决定先执行哪一个。
    看例子:
    int a, b = 1, c = 2;
    a = b = c;
    这个表达式只有赋值符,这样优先级就无法帮助我们呢决定哪个操作先执行。如果a = b先执行,然后 b = c执行。那么a最终取1。如果b = c先执行, a = b后执行,那么a最终取2。到底哪一个先执行?看结合性,复制的结合性是右至左,所以b = c,然后a = b。
    同级的操作符,结合性相同。如果在计算表达式的值时候需要考虑结合性,那么最好把这个表达式一分为二。
来自:计算机科学 / 软件综合
5
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
wubingqp 作者
11年7个月前 IP:未同步
463544
好吧 忘了怎么发图了 26242642_1316521250e9ER.png
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
.........
11年7个月前 IP:未同步
463550
没事多用括号,反正有括号匹配。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
电子不发烧
9年1个月前 IP:广东
763394
谢谢你的图片,大一新生手下这图啦。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
9年1个月前 IP:四川
763469
实际上也就外国人很反感依赖优先级,因为他们记不住[s:20]中国人更烦一堆括号,因为容易花眼
实际上优先级很容易看懂
只要不出现i+++(++i)+i++不定式行为代码。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}