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 ...
随机推荐
- C++ Primer Plus学习:第十一章
运算符重载 使用方法: 在类的声明中定义重载运算符 datatype operator操作符(datatype); 定义:datatype classname:: operator操作符(dataty ...
- Java package
Java中的一个包就是一个类库单元,包内包含有一组类,它们在单一的名称空间之下被组织在了一起.这个名称空间就是包名.可以使用import关键字来导入一个包.例如使用import java.util.* ...
- 微信获取 openid 静默及非静默
<?php /* 需要的微信公众号配置信息 APPID : 绑定支付的APPID APPSECRET : 公众帐号secert */ class Index { // 配置账号信息 privat ...
- xstream 解析xml报文
一.xml一种格式的数据转换为对象 pom.xml引入 <!--javaBean和XML的双向转换--> <dependency> <groupId>com.tho ...
- [LeetCode] Climbing Sairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- jquery不能是使用普通的for循环 因为普通的for循环通过下表获取对象 如果通过下表获取对象的话 会转成dom对象
jquery不能是使用普通的for循环 因为普通的for循环通过下表获取对象 如果通过下表获取对象的话 会转成dom对象
- Impala:新一代开源大数据分析引擎--转载
原文地址:http://www.parallellabs.com/2013/08/25/impala-big-data-analytics/ 文 / 耿益锋 陈冠诚 大数据处理是云计算中非常重要的问题 ...
- ICPCCamp 2017 I Coprime Queries
给出一个长度为\(n\)的正整数序列\(a\),\(m\)次询问\(l,r,x\),问\(max\{i|i\in[l,r],gcd(a_i,x)=1\}\). \(n,m,a_i\le 10^5\). ...
- 【bzoj1004】[HNOI2008]Cards Burnside引理+背包dp
题目描述 用三种颜色染一个长度为 $n=Sr+Sb+Sg$ 序列,要求三种颜色分别有 $Sr,Sb,Sg$ 个.给出 $m$ 个置换,保证这 $m$ 个置换和置换 ${1,2,3,...,n\choo ...
- BZOJ4972 小Q的方格纸
每个格子记录其左下的45°直角梯形区域的和及左下矩形区域的和即可. #include<iostream> #include<cstdio> #include<cmath& ...