上节《编程语法分析之从表达式说起》中说到表达式,他的主要作用就是返回一个值!那这个值具体是多少,就要看表达式的整个运算过程。要理解表达式的运算过程就必须了解“优先级”和“结合律”。

之前讲到表达式,一般有操作数和操作符(或者叫做运算符)组成。“优先级”和“结合律”都是针对操作数和操作符来分析的。现在就来看张表:

 

这张表介绍了“优先级”和“结合律”,优先级数字越小,优先级越高。在优先级相同的情况下,才会考虑“结合律”!

注意上表中,结合方向一栏,右到左的意思就是右结合,左到右,就是左结合。简单说,“结合律”就仅仅分为“左结合”与“右结合”!

为了很好的理解“优先级”和“结合律”我举几个有意义的例子。

 

例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));

编程语法分析之“优先级”和“结合律”的更多相关文章

  1. 高质量C++/C编程指南(林锐)

    推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐   2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐   20 ...

  2. 中兴软件编程规范C/C++

    Q/ZX 深圳市中兴通讯股份有限公司企业标准 (设计技术标准) Q/ZX 04.302.1–2003      软件编程规范C/C++                               20 ...

  3. 高质量c c++编程

    第1章 文件结构 每一个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.还有一个文件用于保存程序的实现(implementation),称为定义(de ...

  4. .NET编程规范

    .NET开发编程规范 第1章 程序的版式 版式虽然不会影响程序的功能,但会影响可读性.程序的版式追求清晰.美观,是程序风格的重要构成因素. 可以把程序的版式比喻为"书法".好的&q ...

  5. [3]第二章 C++编程简介

    (本资料均从 internet 上进行收录整理,若要转载,请与原作者联系) 2.1  机器语言.汇编语言和高级语言 程序员用各种编程语言编写指令,有些是计算机直接理解的,有些则需要中间翻译(tranl ...

  6. 高质量C++/C编程指南

    http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042 高质量C++/C编程指南 文件状态 [  ] 草稿文件 [√] 正式文 ...

  7. C++编程指南续

    三. 命名规则 比较著名的命名规则当推Microsoft公司的"匈牙利"法,该命名规则的主要思想是"在变量和函数名中加入前缀以增进人们对程序的理解".例如所有的 ...

  8. Java开发笔记(十四)几种运算符的优先级顺序

    到目前为止,我们已经学习了Java语言的好几种运算符,包括算术运算符.赋值运算符.逻辑运算符.关系运算符等基础运算符,并且在书写赋值语句时都没添加圆括号,显然是默认了先完成算术.逻辑.关系等运算,最后 ...

  9. C、C++基础和编程风格 (转)

    原文链接 作者:寒小阳时间:2013年8月.出处:http://blog.csdn.net/han_xiaoyang/article/details/10515417.声明:版权所有,转载请注明出处, ...

随机推荐

  1. 从零自学Java-7.使用数组存储信息

    1.创建数组: 2.设置数组的大小: 3.为数组元素赋值: 4.修改数组中的信息: 5.创建多维数组: 6.数组排序. 程序SpaceRemover:显示输入字符串,并将其中所有的空格字符替换为句点字 ...

  2. Zabbix添加Ping外网IP监控

    1.先添加一个HOST,只填写IP即可,如10.1.1.1 2.选择一台客户端,新建item,如下: 3.新建trigger: 注:icmpping[<target>,<packet ...

  3. 插入算法---java实现

    插入排序java代码实现 package algorithms.插入排序; import java.io.BufferedReader; import java.io.InputStreamReade ...

  4. 移动端真机调试抓包,fiddler web debugger

    小白一枚,在公司大神指导下加之找了好多资料才勉强将fiddler的使用摸透,果然很好用. 一.设置手机 二.设置fiddler

  5. November 17th, 2017 Week 46th Friday

    If you shut the door to all errors, truth will be shut out. 你如果拒绝面对错误,真相也会被挡在门外. Sometimes being a f ...

  6. 写博的第一天 0x00

    作为一个大学生,我觉得自己除了睡觉,打游戏,吃饭更应该做点有意义的事情,作为计算机专业的学生,更应该勤奋点,主动去学习.已经要大三了,我认识到这个暑假我必须学点什么了,为了更好的学习,我决定学语言的同 ...

  7. Kafka安装及使用

    zookeeper安装 下载地址:https://www.apache.org/dyn/closer.cgi/zookeeper/ 我这里下载的是zookeeper-3.4.13版本,下载后解压在E: ...

  8. ansible(一)

    Ansible简介 Ansible:Ansible的核心程序Host Lnventory:记录了每一个由Ansible管理的主机信息,信息包括ssh端口,root帐号密码,ip地址等等.可以通过fil ...

  9. jQ判断一个元素是否为空

    // 方法一 if (!$('#jb51').html()) { //http://www.jb51.net 什么都没有找到; } // 方法二 if ($('#jb51').is(":em ...

  10. 阿里开源 iOS 协程开发框架 coobjc!--异步编程的问题与解决方案

    阿里妹导读:刚刚,阿里巴巴正式对外开源了基于 Apache 2.0 协议的协程开发框架 coobjc,开发者们可以在 Github 上自主下载.coobjc是为iOS平台打造的开源协程开发框架,支持O ...