All articles| All Pictures| All Softwares| All Video| Go home page| Write articles| Upload pictures

Reading number is top 10 articles
入门知识:动态网页PHP编程中字符串5个技巧_php资料_编程技术
在Web2.0下的十大AJAX安全漏洞以及成因_.net资料_编程技术
为不同的浏览器载入不同CSS的二种方法_[Html教程]
SQLServer2005中的XML选项详解(2)_[SQL Server教程]
正规化编程学习,谈谈.net命名规范_[Asp.Net教程]
Delphi非矩形窗体
C#+低级Windows,API钩子拦截键盘输入_[Asp.Net教程]
C#中的 ImageAnimator类的应用
delphi中使用游标处理数据
优化SQL Server数据库的方法_[SQL Server教程]
Reading number is top 10 pictures
Absolutely shocked. National geographic 50 animal photographys1
Summer is most suitable for young people to travel in China9
The money of more than 100 countries and regions21
A man's favorite things5
毛俊杰-能量永动机
传奇套装
好身材能把衣服穿出3D效果
Soong ching ling's former residence1
The real super beauty2
含苞欲放的素颜美少女2
Download software ranking
White deer villiage
Unix video tutorial17
c#程序设计案例教程
Prostitutes diary
传奇私服架设教程
jBuilder2006
Tram sex maniac 2 (H) rar bag5
好色的外科大夫
DreamWeaver8
Ashlynn Video1
aaa published in(发表于) 2013/12/17 7:46:31 Edit(编辑)
专家详解:复杂表达式的执行步骤_.net资料_编程技术

专家详解:复杂表达式的执行步骤_.net资料_编程技术

专家详解:复杂表达式的执行步骤_.net资料_编程技术-你的首页-uuhomepage.com

  近日在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++)进行评估,这是个赋值表达式,将右表达式的值赋给左边表达式的值。值得注意的是,对于赋值表达式,表达式本身的值等于左边子表达式的值。


  3.由于"!="表达式左边的子表达式的值已经被评估出来了,下面就执行"!="操作。"!="表达式的是一个布尔值。


  通过以上深入的分析,我们知道这个表达式完成了以下多个功能:


  1.对于指针strDest, strSrc,将strSrc所指的内存空间的值赋给由strDest所指的内存空间。


  2.判断赋值后的strDest所指的内存空间的指是否等于0。


  3.对于指针strDest,strSrc,他们的值分别加1,即指向下一个元素。


  我们可以看出,一个表达式完成了三个功能,表达式写的确实"相当紧凑"。而且这个表达式的值是可以确定的,因为所有的分析都是建立在C 标准的基础上。对于能否在实践的代码中使用这样的代码,这就智者见智了,关键一点就是要遵循项目的代码规范。





添加到del.icio.us 添加到新浪ViVi 添加到百度搜藏 添加到POCO网摘 添加到天天网摘365Key 添加到和讯网摘 添加到天极网摘 添加到黑米书签 添加到QQ书签 添加到雅虎收藏 添加到奇客发现 diigo it 添加到饭否 添加到飞豆订阅 添加到抓虾收藏 添加到鲜果订阅 digg it 貼到funP 添加到有道阅读 Live Favorites 添加到Newsvine 打印本页 用Email发送本页 在Facebook上分享


Disclaimer Privacy Policy About us Site Map

If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)
Copyright ©2011-
uuhomepage.com, Inc. All rights reserved.