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)(其中abc是不同的变量), 不管++a++b++c的求值顺序谁先谁后,结果都会是一致的。

C语言中的序列点的更多相关文章

  1. C语言中的序列点和副作用

    参考: http://www.2cto.com/kf/201210/161225.html

  2. 据序和中序序列或者也许为了一个二进制序列,恢复二进制和打印图像(c语言)

    首先要预购和序,以恢复它: 1.首先,我们使用的是递归的方式来完成 2.递归的最小单位:一个空的树和书的前言和第一序.该序列的第一个元素是树的第一序列根,调用这种方法 3.递归的终止条件是.当这棵树的 ...

  3. 在C语言中利用PCRE实现正则表达式

    1. PCRE简介 2. 正则表达式定义 3. PCRE正则表达式的定义 4. PCRE的函数简介 5. 使用PCRE在C语言中实现正则表达式的解析 6. PCRE函数在C语言中的使用小例子 1. P ...

  4. C语言中的三字母词

    C语言中的三字母词(trigraph) 在ANSI C标准中,定义了9个三字母词(trigraph),三字母词就是几个字符的序列,合起来表示另一个字符.三字母词使C语言环境可以在缺少一些必需字符的字符 ...

  5. 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字

    上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...

  6. R+openNLP︱openNLP的六大可实现功能及其在R语言中的应用

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- openNLP是NLP中比较好的开源工具,R语 ...

  7. unity3d脚本语言中的引用类型

    在之前的文文里有说到,值类型和引用类型,那么这会就单独说下引用类型: Unity3D中的C#语言提供了专门的类型来为开发者提供使用C#开发游戏的便利条件: 在该引擎中,使用UnityEngine命名空 ...

  8. GO语言中的几个关键思想

    GO语言的设计理念与C++,Java,Python之流大相径庭. 一.没有函数重载 GO语言里面没有函数重载,Java.C#.C++三位大牛都是支持函数重载的,Python虽然不支持函数重载,但是支持 ...

  9. JSON在各种语言中的运用

    1. JSON数据格式 JSON(JavaScript Object Notation) 从结构上看,所有的数据最终都可以分成三种类型:  第一种类型是scalar(标量),也就是一个单独的strin ...

随机推荐

  1. 技嘉主板+AMD CPU开启CPU虚拟化方法

    硬件环境:技嘉AB350+AMD Ryzen 5 1600X 由于安装虚拟机的需要,所以要开启CPU的虚拟化. 首先进入BIOS. 然后如图:(M.I.T-高级频率设定-CPU超频进阶设置-SVM M ...

  2. slf4j与logback的结合使用

    参考:http://my.oschina.net/ydsakyclguozi/blog/412240 一.logback的介绍 Logback是由log4j创始人设计的又一个开源日志组件.logbac ...

  3. 【第八周】【新蜂】新NABCD

    由小组成员宫成荣撰写 一.小组项目申请时提交的NABCD: 痛点:普通的俄罗斯方块是不现实距离下一级有多远的,我们的游戏能显示距离下一等级游戏有多远.方便玩家体验. nabc: n:能满足大多数玩家的 ...

  4. Jmeter 快速入门--初识线程组

    添加线程组 (1)thread group(线程组),setup thread group相当于lr初始化“环境”的初始化脚本,teardown thread group相当于lr测试完毕后对应的清除 ...

  5. Bootstrap-tagsinput标系统使用心得

    最近工作中由于需求使用到了Bootstrap-tagsinput标系统,我的需求是: 1)能够从后台数据库获取标签信息展示到前端页面: 2)能够实现输入标签添加到后台,并ajax刷新页面: 3)能够实 ...

  6. 第92天:CSS3中颜色和文本属性

    一.颜色的表示方式 1. rgba(255,0,0,0.1)  rgba是代表Red(红色) Green(绿色) Blue(蓝色)和 Alpha透明度.虽然它有的时候被描述为一个颜色空间 新增了RGB ...

  7. angularjs 指令间相互调用

    <div ng-app="app"> <div ng-controller="myctl"> <button superman s ...

  8. 在Linux上编译使用tcmalloc

    项目需要使用tcmalloc,比较简单的方法是安装tcmalloc相关包(gpertools)后,将tcmalloc的静态库提取出来,在编译项目内核(执行makefile)时,链接上静态库即可. 这里 ...

  9. Count the string HDU - 3336

    题意: 求一个字符串的每个前缀在这个字符串中出现次数的加和 解析: 默默的骂一句...傻xkmp..博主心里气愤... 拓展kmp就好多了... 因为拓展kmp每匹配一次   就相当于这些前缀出现了一 ...

  10. Cows and Cars UVA - 10491 (古典概率)

    按照题目的去推就好了 两种情况 1.第一次选择奶牛的门  概率是 a/(a+b) 打开c扇门后  除去选择的门 还剩 a-1-c+b扇门  则选到车的概率为b/(a-1-c+b) 2.第一次选择车的门 ...