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 ...
随机推荐
- lintcode-423-有效的括号序列
423-有效的括号序列 给定一个字符串所表示的括号序列,包含以下字符: '(', ')', '{', '}', '[' and ']', 判定是否是有效的括号序列. 样例 括号必须依照 "( ...
- JS 中substring() , substr(), slice() 的区别
substr(start, length) : 截取从start索引开始的字符,长度为length的字符串 substring(start, end) : 截取从start索引开始的字符,以end索引 ...
- jQuery之offset,position
获取/设置标签的位置数据 * offset(): 相对页面左上角的坐标 * position(): 相对于父元素左上角的坐标. 需求: 1. 点击 btn1 打印 div1 相对于页面左上角的位置 打 ...
- 【beta】Scrum站立会议第7次....11.9
小组名称:nice! 组长:李权 成员:于淼 刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.9 12:00——12:30 地点:传媒西楼220室 本次对beta阶段 ...
- PAT 甲级 1059 Prime Factors
https://pintia.cn/problem-sets/994805342720868352/problems/994805415005503488 Given any positive int ...
- Android定位测试(深坑)
问题:我们是一个海外app,市场部去马来西亚打开那边的市场,发现了一个问题,就是我们的app定位有问题,还是成都的定位,主要原因是在马来西亚使用这个app,请求中带的经纬度参数是成都的,导致服务器返回 ...
- C# 为VB6.0程序模拟串口数据
为VB6.0编写程序模拟数据测试使用. 一.VB6.0 控件MSComm,来发送接收串口数据 CommPort 属性设置并返回通讯端口号,虚拟端口为COM2. Settings 属性设置并返回端口的波 ...
- 插件-3D轮播图
先上效果图 查看实例点击 这里 这个栗子中,可以选择展示 5 张 或者展示 3 张,即使是只有一个slide,也可以完成布局,正常轮播,麻麻再也不用怕只有4个slid而不能用这种轮播啦! 本栗实现原 ...
- poj2299——Ultra-QuickSort
Description In this problem, you have to analyze a particular sorting algorithm. The algorithm proce ...
- DP——P2300 合并神犇
题目背景 loidc来到了NOI的赛场上,他在那里看到了好多神犇. 题目描述 神犇们现在正排成一排在刷题.每个神犇都有一个能力值p[i].loidc认为坐在附近的金牌爷能力参差不齐非常难受.于是loi ...