1 表达式的求值顺序问题:

函数参数的评估求值顺序


分析下面代码片段的输出结果:
int i = 2010;
printf("The results are: %d %d", i, i+=1 );
函数参数的评估求值并没有固定的顺序,所以,printf() 函数的输出结果可能是2010、
2011,也可能是2011、2011 。
类似的还有:
printf("The results are: %d %d", p(), q() );
p() 和q() 到底谁先被调用,这是一个只有编译器才知道的问题。
为了避免这一问题的发生,有经验的工程师会保证凡是在参数表中出现过一次以上的变
量,在传递时不改变其值。即使如此也并非万无一失,如果不是足够小心,错误的引用同样
会使努力前功尽弃,如下所示:
int para = 10;
int &rPara = para;
int f(int, int);
int result = f(para, rPara *= 2);
推荐的形式应该是:
int i = 2010;
printf("The results are: %d %d", i, i+1 );
int para = p();
printf("The results are: %d %d", para, q() );

int para = 10;
int f(int, int);
int result = f(para, para*2);

操作数的评估求值顺序

操作数的评估求值顺序也不固定,如下面的代码所示:
a = p() + q() * r();
三个函数p()、q() 和r() 可能以6 种顺序中的任何一种被评估求值。乘法运算符的高优
先级只能保证q() 和r() 的返回值首先相乘,然后再加到p() 的返回值上。所以,就算加上再
多的括号依旧不能解决问题。
幸运的是,使用显式的、手工指定的中间变量可以解决这一问题,从而保证固定的子表
达式评估求值顺序:
int para1 = p();
int para2 = q();
a = para1 + para2 * r();
这样,上述代码就为p()、q() 和r() 三个函数指定了唯一的计算顺序:p() → q() → r()。

另外,有一些运算符自诞生之日起便有了明确的操作数评估顺序,有着与众不同的可靠
性。
例如下面的表达式:
(a < b) && (c < d)
C/C++ 语言规定,a < b 首先被求值,如果a < b 成立,c < d 则紧接着被求值,以计算整
个表达式的值。但如果a 大于或等于b,则c < d 根本不会被求值。类似的还有||。这两个运
算符的短路算法特性可以让我们有机会以一种简约的、符合习惯用法的方式表达出很复杂的
条件逻辑。
三目条件运算符 ?: 也起到了把参数的评估求值次序固定下来的作用:
expr1 ? expr2 : expr3
第一个表达式会首先被评估求值,然后第二个和第三个表达式中的一个会被选中并评估

求值,被选中并评估求值的表达式所求得的结果就会作为整个条件表达式的值。
此外,在建议6 中将会详细介绍的逗号运算符也有固定的评估求值顺序。
请记住:
表达式计算顺序是一个很繁琐但是很有必要的话题:
针对操作符优先级,建议多写几个括号,把你的意图表达得更清晰。
注意函数参数和操作数的评估求值顺序问题,小心其陷阱,让你的表达式不要依赖计
算顺序。

2 逗号运算符

逗号分隔的表达式由于语言规则的不直观,容易产生理解上的误差。在使用逗号分
隔表达式时,C++ 会确保每个表达式都被执行,而整个表达式的值则是最右边表达式的
结果。

3 结构体中元素的布局

字节对齐

现代计算机中内存空间都是按照字节来划分的,从理论上来讲,对变量的访问可以从任
何地址开始;但在实际情况中,为了提升存取效率,各类型数据需要按照一定的规则在空间
上排列,这使得对某些特定类型的数据只能从某些特定地址开始存取,以空间换取时间,这就是字节对齐。

结构体默认的字节对齐一般满足三个准则:
(1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除。
(2)结构体每个成员相对于结构体首地址的偏移量(offset)都是成员自身大小的整数
倍,如有需要,编译器会在成员之间加上填充字节(Internal Adding)。
(3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在
最末一个成员之后加上填充字节(Trailing Padding)。

在编程应用中,如果空间紧张,需要考虑节约空间,那么就需要将结构体中的各个变量
按照上面的原则进行排列。基本的原则是:把结构体中的变量按照类型大小从小到大依次声
明,尽量减少中间的填充字节。

在某些时候,还可以通过编译器的pack 指令调整结构体的对齐方式。#pragma pack 的
基本用法为:
#pragma pack( n )
n 为字节对齐数,其取值为1、2、4、8、16,默认是8。
#pragma pack(1)// 设置1 字节对齐
struct A // 结构体A
{
int a;
char b;
short c;
};
将结构体A 的对齐方式设为1 字节对齐,那么A 就不再有填充字节了,sizeof(A) 的结
果即为各元素所占字节之和7。
请记住:
了解结构体中元素的对齐规则,合理地为结构体元素进行布局。这样不仅可以有效地节
约空间,还可以提高元素的存取效率。

2012.4.16总结(二)相关推荐

  1. DWR入门教程(http://www.cnblogs.com/cyjch/archive/2012/02/16/2353758.html)

    文章转载自<http://www.cnblogs.com/cyjch/archive/2012/02/16/2353758.html>,多谢大牛分享! DWR入门教程 DWR(Direct ...

  2. http://www.cnblogs.com/xia520pi/archive/2012/05/16/2504205.html

    http://www.cnblogs.com/xia520pi/archive/2012/05/16/2504205.html http://www.cnblogs.com/madyina/p/370 ...

  3. 网络云存储技术Windows server 2012 (项目十二 为企业构建虚拟共享服务(工作组模式下的DFS))

    网络云存储技术Windows server 2012 (项目十二 为企业构建虚拟共享服务(工作组模式下的DFS)) 前言 网络存储技术,是以互联网为载体实现数据的传输与存储,它采用面向网络的存储体系结 ...

  4. 使用ContactsContract APIhttp://www.cnblogs.com/carbs/archive/2012/07/16/2593295.html

    转自:http://www.cnblogs.com/carbs/archive/2012/07/16/2593295.html 自Android 2.0(API Level 5)开始,Android平 ...

  5. ][互动大奖] Webby Awards 2012 第16届威比奖

    http://blog.sina.com.cn/s/blog_59fe4e920102eb7q.html 素有"互动界的奥斯卡奖"称号的Webby Awards威比奖历来是国际公认 ...

  6. 混合易失和非易失主存的日志结构文件系统NOVA[FAST'16]随笔二

    序言 没成想,本想用一篇博文写完的,偶然发现博文后面文字显示不了,最后才发现是因为符号原因"<>"隐藏了后面的文字表示.那么为了把故事讲完整,所以我写了这篇后续博客.内 ...

  7. SCCM 2012系列16 操作系统播发⑤

    添加了操作系统映像,也创建了任务序列,那么我们改对创建的任务序列编辑一下了,以满足我们播发下去系统的要求是我们想要的,比如分区是怎么样的,当然分区不是固化的,是按照百分比来进行划分的,详细怎么样的,请 ...

  8. 2012.4.16总结(四)

    ++前缀和后缀运算符 前缀效率优于后缀运算符,这是因为在运行操作符之前编译器需要建立一个临时的对象,而这还要从函数重载说起. 重载函数间的区别取决于它们在参数类型上的差异,但不论是自增的前缀还是后缀, ...

  9. 2012.4.16总结(三)

    1 由于强制转型无所不能,会给C++ 程序带来很大的安全隐患,因此建议在C++ 代码中,努力将强制转型减到最少 将较大的整数转换为较短的数据类型时,会产生无意义的结果,而程序员可能被蒙在鼓里.正如下面 ...

最新文章

  1. presto能连接mysql和hive吗_Presto连接Hive
  2. 1264: [AHOI2006]基因匹配Match
  3. 《Docker——容器与容器云》:第五章 构建自己的容器云
  4. Split和Substring的用法
  5. Mynavi Programming Contest 2021(AtCoder Beginner Contest 201)题解
  6. 哈老师一到的飞鸽传书
  7. 一文尽览 ECCV 2020 旷视研究院15篇论文
  8. A better zip bomb,比例28000000:1「V2」
  9. html 自动执行vbs代码,vbs脚本教程 怎样在bat脚本中调用vbs脚本
  10. 2022年双十一有哪些电子产品值得入手、超值电子产品推荐清单
  11. 关于matlab的erf与erfc
  12. 历时一个月整理2021金三银四Java面试题汇总,足足127页!
  13. 月之数 HDU2502
  14. 学计算机专业的打字要快么,怎样学电脑打字最快电脑新手如何快速学会打字
  15. 京东区块链技术实践白皮书2020
  16. 如何安装和设置Eufy Lumos Wi-Fi智能灯泡
  17. 自适应遗传算法 matlab,自适应遗传算法MATLAB代码
  18. ECharts3D地图 简单制作省份地图
  19. 关于接口的规范和文档总结
  20. java驾校管理系统代码_JAVA课程设计驾校管理系统

热门文章

  1. 统计学常见分布、概念
  2. android蓝牙hfp client使用例
  3. java synchronized互斥锁使用
  4. UE4之变量、定时器和事件
  5. openGL--glBlendFunc颜色混合
  6. android jni 多线程,[Android]JNI进阶--线程池
  7. java 百度副文本_spring boot 、springMVC环境集成百度ueditor富文本编辑器
  8. matlab 矩阵除法计算,Matlab中的矩阵除法有问题???
  9. ft2232驱动安装方法_win7系统无法安装打印机驱动程序的解决方法
  10. map.setTerrain is not a function