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. MyEclipse+SSH开发环境配置

    MyEclipse+Struts+Hibernate+Mysql开发环境配置 软件: jdk-6u22-windows-x64.exe apache-tomcat-6.0.29.exe mysql-5 ...

  2. ACM解题之在线翻译 Give Me the Number

    Give Me the Number Time Limit: 2 Seconds                                     Memory Limit: 65536 KB  ...

  3. Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错,

    Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错, 这里总结一些可能的原因和解决方案,给需要的朋友: 说道undefined reference err ...

  4. mysql中约束

    约束 什么叫做约束? 约束,就是要求数据需要满足什么条件的一种“规定”. 主要有如下几种约束: 主键约束:形式: primary key ( 字段名); 含义(作用):使该设定字段的值可以用于“唯一确 ...

  5. iOS pch文件的创建

    3.iso pch头文件的创建  输入文件名的时候记得打钩 3.1.在Build Settings 里搜索pref就能找到preflx, 点击设置相对路径 $(SRCROOT) +路径:成功了就会显示 ...

  6. 【bzoj2300】[HAOI2011]防线修建 离线+STL-set维护凸包

    题目描述 给你(0,0).(n,0).(x,y)和另外m个点,除(0,0)(n,0)外每个点横坐标都大于0小于n,纵坐标都大于0. 输入 第一行,三个整数n,x,y分别表示河边城市和首都是(0,0), ...

  7. 洛谷 P2763 试题库问题(网络流24题之一)

    题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...

  8. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)

    A 每次可以换一个或不换,暴力枚举位置即可 B 模拟 C 二分答案.. 边界可以优化r=totb/(tota-p),二分可以直接(r-l>=EPS,EPS不要太小,合适就好),也可以直接限定二分 ...

  9. 【noip2018】【luogu5024】保卫王国

    题目描述 Z 国有nn座城市,n - 1n−1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需要满足如下几个条 ...

  10. django 自定义认证

    在Django中自定义身份验证 Django 自带的认证系统足够应付大多数情况,但你或许不打算使用现成的认证系统.定制自己的项目的权限系统需要了解哪些一些关键点,即Django中哪些部分是能够扩展或替 ...