编程语法分析之“优先级”和“结合律”
上节《编程语法分析之从表达式说起》中说到表达式,他的主要作用就是返回一个值!那这个值具体是多少,就要看表达式的整个运算过程。要理解表达式的运算过程就必须了解“优先级”和“结合律”。
之前讲到表达式,一般有操作数和操作符(或者叫做运算符)组成。“优先级”和“结合律”都是针对操作数和操作符来分析的。现在就来看张表:
这张表介绍了“优先级”和“结合律”,优先级数字越小,优先级越高。在优先级相同的情况下,才会考虑“结合律”!
注意上表中,结合方向一栏,右到左的意思就是右结合,左到右,就是左结合。简单说,“结合律”就仅仅分为“左结合”与“右结合”!
为了很好的理解“优先级”和“结合律”我举几个有意义的例子。
例1、这个例子主要从“结合律”出发,讨论左结合与右结合的特点。
所谓结合,就是多个东西结合成为一个整体,而成为一个新的东西。当一个操作符是一个左结合且为双目运算符时,他会把他左边的东西整个当作一个整体并与之结合,右边的只认离他最近的一个。(右结合与之相反)
如:(这是一个C++例子,能很好的理解结合这个概念)
对于第二个<<运算符而言,他会把他左边的全部当中一个整体,及把当作一个整体,这个整体其实就是个表达式,他是一个值,他的值就是std::cout的值。
而对于第一个<<运算符而言,在他的右边他只认“Hello,World!”及右边的只认离他最近的一个。
在原文<Accelerated C++>中是这么解释的;
如果您多C++不熟悉,我们就来看第二例子:
例2、一个超级简单的表达式,此时你应该有更深的认识:
a + b + c
首先,此表达式中,操作符都是加号,大家优先级相同,所以转而考虑结合性,+是左结合。
所以第一个加号先与a结合,并且只认右边和他最近的b,而对于第二个加号,会把a+b当作一个整体,并与之结合,然后只认右边和他最近的c。结果就是((a) + b) + c 。
如果前两个例子都不过瘾,我们来看第三个例子:
例3、这个例子需要兼而考虑优先级”和“结合律”。
(* ( ( void (*)() )0 ) )()
这里操作符有小括弧——强制转换符(形式上也是小括弧),解引用符,操作数只有一个,就是0;操作符都是针对操作数的。
我们先从0开始看,和0最近的是小括弧,这个小括弧里面是个void (*)()这其实是个类型——函数指针类型,用小括弧把类型括起来,这个小括弧其实是强制转换符。那么( void (*)() )0 这个表达式结合起来,就表示把0,强制转换为函数指针类型。
在往外又是一个小括弧,这个小括弧就是说小括弧内部是一个结合的整体。此时由于( void (*)() )0是一个整体而且表示一个函数指针,所以把( void (*)() )0替换为p,结果就是(* p )(),这句话的意思其实就是利用函数指针p调用函数。而这p其实是指向地址0的。所以这句表达式的副作用就是,让程序指针PC跳到地址0,及完成一个软件复位的功能。
进一步讨论如果,去掉其中的一层括号:
(* ( void (*)() )0 )()
那么一开始有两个操作符针对操作数0,一个是强制转换符(类型),一个是解引用*观察上表可知(类型)和 * 的优先级都是2,优先级相同,而结合性是右结合,简化一下表达式再分析:
(* ( 类型 )0 )()
因为是右结合,所以*会把右边的( 类型 )0当作一个整体,及 ( 类型 )先和0结合,所以结论是去掉这层括号含义不变!
趁热打铁,我们来看第四个例子:
例4、ph->pNext->pNext->pNext->pNext->pNext
这种表达式通常是在链表的访问中见到,别看他这么长其实也就返回是一个值,所以不必怕它。
ph是个头指针,->这个符号查表得知是左结合,及左边的看成整体,右边的只认一个那么ph->pNext就可以被单独分离出来并且结合到一起成为一个整体,
ph->pNext看成整体之后,其实就是返回一个指针,及第0个节点中存放的指针值!而这个指针指向第1个节点。所以ph->pNext可以用p1代替。
剩下的p1->pNext->pNext->pNext->pNext,依照上面的方法如法炮制就得到p2->pNext->pNext->pNext。最终就得到p4->pNext.
如果说ph指向第0个节点,p4->pNext最终的结果其实就是第4个节点中存放的指针值,指针指向第5个节点。这也就是整个表达式的结果。
最后一个例子引入,逗号表达式作为饭后甜点。
例5、逗号表达式
逗号表达式形如:表达式1,表达式2
首先,逗号表达式,也是个表达式,逗号表达式作为整体也返回一个值!
其次,整个逗号表达式的结果为表达式2的结果。
可能有的同学要发问了,那表达式1不是个打酱油的?其实,表达式1一般是为表达式2做个铺垫,如:(从MFC截取的一个例子)
表达式1其实是给str赋值,表达式2就是一个比较语句,那么if只会判断表达式2的结果是否为真,而不会理会表达式1的返回值。
在使用逗号表达式时,一定要注意优先级的问题,因为“,”的优先级比“=”的优先级还要低。
例如:a = 3*5 , a*4; 由于“,”的优先级比“=”的优先级低,所以a = 3*5先结合,算出a等于15,然后a*4得到60.再根据“整个逗号表达式的结果为表达式2的结果”
所以整个表达式(a = 3*5 , a*4)的结果是60.
具体测试方法为:
int a;
printf("%d",(a = 3*5 , a*4));
编程语法分析之“优先级”和“结合律”的更多相关文章
- 高质量C++/C编程指南(林锐)
推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐 2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐 20 ...
- 中兴软件编程规范C/C++
Q/ZX 深圳市中兴通讯股份有限公司企业标准 (设计技术标准) Q/ZX 04.302.1–2003 软件编程规范C/C++ 20 ...
- 高质量c c++编程
第1章 文件结构 每一个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.还有一个文件用于保存程序的实现(implementation),称为定义(de ...
- .NET编程规范
.NET开发编程规范 第1章 程序的版式 版式虽然不会影响程序的功能,但会影响可读性.程序的版式追求清晰.美观,是程序风格的重要构成因素. 可以把程序的版式比喻为"书法".好的&q ...
- [3]第二章 C++编程简介
(本资料均从 internet 上进行收录整理,若要转载,请与原作者联系) 2.1 机器语言.汇编语言和高级语言 程序员用各种编程语言编写指令,有些是计算机直接理解的,有些则需要中间翻译(tranl ...
- 高质量C++/C编程指南
http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042 高质量C++/C编程指南 文件状态 [ ] 草稿文件 [√] 正式文 ...
- C++编程指南续
三. 命名规则 比较著名的命名规则当推Microsoft公司的"匈牙利"法,该命名规则的主要思想是"在变量和函数名中加入前缀以增进人们对程序的理解".例如所有的 ...
- Java开发笔记(十四)几种运算符的优先级顺序
到目前为止,我们已经学习了Java语言的好几种运算符,包括算术运算符.赋值运算符.逻辑运算符.关系运算符等基础运算符,并且在书写赋值语句时都没添加圆括号,显然是默认了先完成算术.逻辑.关系等运算,最后 ...
- C、C++基础和编程风格 (转)
原文链接 作者:寒小阳时间:2013年8月.出处:http://blog.csdn.net/han_xiaoyang/article/details/10515417.声明:版权所有,转载请注明出处, ...
随机推荐
- Nodejs搭建wss服务器
首先使用OpenSSL创建自签名证书: #生成私钥key文件 openssl genrsa > /path/to/private.pem // #通过私钥文件生成CSR证书签名 openssl ...
- Android学习 -- Activity 以及Activity之间值传递
项目结构如图 关键代码如下 strings.xml文件代码如下: <?xml version="1.0" encoding="utf-8"?> &l ...
- TestLink笔记(一):环境配置+安装
注:转载请加上原文链接,谢谢! 本文的安装环境是Windows操作系统. (一) 前期准备 1.XAMPP下载(下载5.6的版本) https://www.apachefriends.org/ ...
- Git仓库初始化与推送到远端仓库
以下命令为Git仓库初始化,添加远端代码托管仓库,以及推送到远端仓库的命令. 以 "github.com"为远端仓库做示例 # Git 库初始化 git init # 将文件添加到 ...
- Angular 过滤器的简单使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 十个强大的DevOps基础设施自动化工具,不容错过
Devops基础设施自动化的工具 有许多工具用于基础设施自动化.使用哪个工具决定于体系结构和基础设施的需求.下面我们列出了一些伟大的工具,用于不同类别配置管理.编制.持续集成.监控等. 1.Chef ...
- 《SQL Server 2008从入门到精通》--20180716
1.锁 当多个用户同时对同一个数据进行修改时会产生并发问题,使用事务就可以解决这个问题.但是为了防止其他用户修改另一个还没完成的事务中的数据,就需要在事务中用到锁. SQL Server 2008提供 ...
- Cisco ASA 使用ASDM 配置管理口 方法
CISCO ASA防火墙ASDM安装和配置 准备一条串口线一边接台式机或笔记本一边接防火墙的CONSOLE 接口,通过CRT或者超级终端连接ASA在用ASDM图形管理界面之前须在串口下输入一些命令开启 ...
- 大话存储 1 - 走进计算机IO世界
组成计算机的三大件:CPU,内存和IO. 1 总线 总线就是一条或者多条物理上的导线,每个部件都接到这些导线上,同一时刻只能有一个部件在接收或者发送. 仲裁总线:所有部件按照另一条总线,也就是仲裁总线 ...
- NFS 系统的搭建
问题: 由于工作,需要,不断得进行挂在硬盘重装系统,NFS 系统给了我一个很好的解决方案.于是决定写一篇博客,防止以后再次使用的时候,能够很快得重新建立NFS 文件系统. 调研: NFS(Networ ...