C语言中的序列点
TAG: C, 序列点
DATE: 2013-08-07
序列点是程序执行序列中一些特殊的点。 当有序列点存在时,序列点前面的表达式必须求值完毕,并且副作用也已经发生, 才会计算序列点后面的表达式和其副作用。
什么是副作用?举例子来说明。
int a = 5;
int b = a ++;
在给b赋值的语句中,表达式a++
就有副作用,它返回a
当前的值5后,要对a
进行加1的操作。
哪些符号会生成序列点呢?
",
"会生成序列点。
",
"用于把多条语句拼接成一条语句。 例如:
int b = 5;
++ b;
可由",
"拼接成
int b = 5, ++b;
因为",
"会产生序列点,所以",
"左边的表达式必须先求值,如果有副作用,副作用也会生效。然后才会继续处理",
"右边的表达式。
&&
和||
会产生序列点
逻辑与 &&
和逻辑或 ||
会产生序列点。
因为&&
支持短路操作,必须先将&&
左边的表达式计算完毕,如果结果为false
,则不必再计算&&
右边的表达式,直接返回false
。
||
和&&
类似。
?:
中的"?
"会产生序列点
三元操作符 ?:
中的"?
"会产生序列点。 如:
int a = 5;
int b = a++ > 5? 0 : a;
b
的结果是什么?因为"?
"处有序列点,其左边的表达式必须先求值完毕。 a++ > 5
在和5比较时,a
并没有自增,所以表达式求值为false
。 因为"?
"处的序列点,其左边表达式的副作用也要立即生效,即a
自增1,变为6。 因为"?
"左边的表达式求值为false
,所以三元操作符?:
返回:
右边的值a
。 此时a
的值是6,所以b
的值是6。
序列点之间的执行顺序
奇怪的C代码中给出的例子。
int i = 3;
int ans = (++i)+(++i)+(++i);
(++i)+(++i)+(++i)
之间并没有序列点,它们的执行顺序如何呢? gcc编译后,先执行两个++i
,把它们相加后,再计算第三个++i
, 再相加。而Microsoft VC++编译后,先执行三个++i
,再相加。 两者得到的结果不同,谁对谁错呢?
谁也没有错。C标准规定:两个序列点之间的执行顺序是任意的。 当然这个任意是在不违背操作符优先级和结合特性的前提下的。 这个规定的意义是为编译器的优化留下空间。
知道这个规定,我们就应该避免在一行代码中重复出现被递增的同一个变量, 因为编译器的行为不可预测。 试想如果(++i)+(++i)+(++i)
换成(++a)+(++b)+(++c)
(其中a
、b
、c
是不同的变量), 不管++a
,++b
和++c
的求值顺序谁先谁后,结果都会是一致的。
C语言中的序列点的更多相关文章
- C语言中的序列点和副作用
参考: http://www.2cto.com/kf/201210/161225.html
- 据序和中序序列或者也许为了一个二进制序列,恢复二进制和打印图像(c语言)
首先要预购和序,以恢复它: 1.首先,我们使用的是递归的方式来完成 2.递归的最小单位:一个空的树和书的前言和第一序.该序列的第一个元素是树的第一序列根,调用这种方法 3.递归的终止条件是.当这棵树的 ...
- 在C语言中利用PCRE实现正则表达式
1. PCRE简介 2. 正则表达式定义 3. PCRE正则表达式的定义 4. PCRE的函数简介 5. 使用PCRE在C语言中实现正则表达式的解析 6. PCRE函数在C语言中的使用小例子 1. P ...
- C语言中的三字母词
C语言中的三字母词(trigraph) 在ANSI C标准中,定义了9个三字母词(trigraph),三字母词就是几个字符的序列,合起来表示另一个字符.三字母词使C语言环境可以在缺少一些必需字符的字符 ...
- 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字
上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...
- R+openNLP︱openNLP的六大可实现功能及其在R语言中的应用
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- openNLP是NLP中比较好的开源工具,R语 ...
- unity3d脚本语言中的引用类型
在之前的文文里有说到,值类型和引用类型,那么这会就单独说下引用类型: Unity3D中的C#语言提供了专门的类型来为开发者提供使用C#开发游戏的便利条件: 在该引擎中,使用UnityEngine命名空 ...
- GO语言中的几个关键思想
GO语言的设计理念与C++,Java,Python之流大相径庭. 一.没有函数重载 GO语言里面没有函数重载,Java.C#.C++三位大牛都是支持函数重载的,Python虽然不支持函数重载,但是支持 ...
- JSON在各种语言中的运用
1. JSON数据格式 JSON(JavaScript Object Notation) 从结构上看,所有的数据最终都可以分成三种类型: 第一种类型是scalar(标量),也就是一个单独的strin ...
随机推荐
- OC创建对象并访问成员变量
1.创建一个对象 Car *car =[Car new] 只要用new操作符定义的实体,就会在堆内存中开辟一个新空间 [Car new]在内存中 干了三件事 1)在堆中开辟一段存储空间 2)初始化成员 ...
- Strust2: 工作流程
以下为Struts2的体系结构图: Struts2框架处理用户请求,大体分为以下几个过程: (1)用户发出一个HttpServletRequest请求 (2)请求经过一系列过滤器,最后达到Filter ...
- (一)java数据类型图
┏数值型━┳━整数型:byte short int long ┏基本数据类型━━┫ ┗━浮点型:float double ...
- Java JVM多线程
- QQueue与QStack使用
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QQueue与QStack使用 本文地址:http://techieliang.com ...
- freemarker中空值 null的处理 ?exists ?if_exists ?default(“”)
exists:由空值测试运算符的引入,它被废弃了. exp1?exists 和 exp1??是一样的, ( exp1)?exists 和(exp1)??也是一样的. if_exists:由默认值运算符 ...
- 解决java图形界面label中文乱码
第一:在你的具有main函数的类也即你应用运行的主类上点击右键,选择Run As中的Run Configurations,如下图:java,awt,中文方框,中文乱码第二,在Arguments标签下的 ...
- IDEA换行CRLF, LF, CR的解释和默认设置
在window下开发有一个大坑,就是换行默认是CRLF,也就是回车换行,但是Linux下只有换行LF,这样代码提交后,会出现编译问题,所以最好的办法是在IDEA下设置默认为LF. 首先我们先介绍CRL ...
- 解决Lenovo(ldeapad)笔记本F1-F12功能键操作无效的问题
1.操作条件:Lenovo笔记本自带的“一键恢复”按钮 2.操作方法:上下键为切换选项,回车键(Enter)为确定选择 (1)在笔记本电脑关机状态下,使用曲别针或其他物件按下笔记本自带的“一键恢复按钮 ...
- 【C++】为多态基类声明virtual析构函数
来自<Effective C++>条款07:为多态声明virtual析构函数 当derived class对象经由一个base class指针被删除,而该base class带着一个non ...