2007-05-28

专家详解:复杂表达式的执行步骤

来源: 网络摘编 作者:佚名 评论 0 条
 

近日在CSDN上闲逛的时候,注重到一个帖子:

  ((*strDest =*strSrc )!='\0'); 哪儿前辈可以解释下里面具体执行的步骤呢?

  对于这样的表达式,我们通常会有这样三种看法:

  1.这种写法不但没有错误(当然也没有BUG),而且写法紧凑。

  2.这种写法虽然没有错误,但是不够直观,理解起来有点麻烦,可能还会导致理解错误。

  3.这种写法中存在未定义的地方,执行结果可能是错误的。

  粗略来看,这三种说法都有点道理。我顿时有了刨根问底的爱好,想对这个问题进行一次深入的分析。对于这种组合表达式,在分析的时候我们应该抓住两个要害的概念:优先级(Precedence)和关联性(Associativity)。

  1.优先级(Precedence)。优先级决定了那些表达式的值先被评估,那些表达式的值后被评估。通常情况下,优先级高的表达式的值先被评估出来后,然后用评估的结果再去评估那些优先级低的表达式。所以假如我们将优先级搞反了,评估出来的结果是错误的。

  2.(Associativity)。对于二目表达式,关联性决定了左边的表达式还是右边的表达式先被评估,先被评估出来的结果再用来评估另外的表达式。

  再抓住这两个要害的同时,我们还应该分清什么是表达式的值,什么是变量的值。我们在评估表达式的时候,我们感爱好的是表达式的值,而不是构成表达式的某些变量的值。在很多情况下,表达式的值和某些变量的值是一致的,所以我们很轻易混淆表达式的值和变量的值。要知道,在有些情况下,表达式的值并不和某些变量的值相同。

  有了上面的理论来武装我们,对表达式的分析就显得游刃有余了:

  1. 很明显,上面的表达式是一个组合表达式。组合表达式由子表达式组成,子表达式又可能是组合表达式,这样就形成了一个树状的数据结构。对表达式的评估就类似于对树结点的遍历。首先我们应该注重到"()"操作符,它具有最高的优先级,所以从整体来看,整个表达式应该是个"!="操作。"!="左边又是一个组合表达式,而右边是一个常量"\0',很明显下面的工作就是评估(*strDest =*strSrc )。

  2.在这一步,我们要对表达式(*strDest =*strSrc )进行评估。由于赋值表达式具有较低的优先级,所以表达式 又可以写成:(*strDest ) = (*strSrc ),所以整个表达式是个"="操作,"="左边又是一个组合表达式,右边也是一个组合表达式,这里就需要从关联性来判定左边还是右边也被评估。由于"="的关联性是从右到左,所以(*strSrc )先被评估,(*strDest )后被评估。

  2.1 在这一步,我们要对表达式(*strSrc )进行评估。由于" "的优先级大于"*",所以表达式又可以写成:*(strSrc )。我们要先对表达式strSrc 进行评估,然后用表达式的值再去评估*(strSrc )的值。对于表达式strSrc ,这里要需要注重区分变量的值和表达式的值。对于"后增1"表达式,表达式的值是变量strSrc的值,然后变量strSrc的值会"加1",也就是说表达式的值是strSrc变化前的值,而strSrc的值会发生变化。值得注重的是,我们知道strSrc的值会发生变化,但是我们却不知道strSrc的值发生变化的具体时间,这个变化具体的执行时间由编译器决定了,这就决定了任何依靠strSrc的表达式的值是不确定的,具体的值依靠编译器的实现。完成了对strSrc 的评估后,取值操作符就对表达式的值所对应的内存空间进行取值操作。

  2.2 在这一步,我们要对表达式(*strDest )进行评估。具体的评估的分析完全和2.1中的分析一致。

  2.3 在这一步,我们要对表达式(*strDest ) = (*strSrc )进行评估,这是个赋值表达式,将右表达式的值赋给左边表达式的值。值得注重的是,对于赋值表达式,表达式本身的值等于左边子表达式的值。
共2页: 上一页 1 [2] 下一页

(本文仅表明作者个人观点,不代表本站及其管理员立场.) 推荐 收藏 投稿 打印 返回 关闭
上一篇:ASP.NET动态网页制作初学者备忘录  
下一篇:学习ASP之SQL语句查询效率和安全性
    评论加载中…
 推荐文章
     

网站首页  -  网站地图 -   站长论坛  -  网站投稿  -    -  网站管理
Copyright © 2008 芜湖站长站 All Rights Reserved 皖ICP备07500611号