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

  • 相关阅读:
    安卓使用socket建立通信客户端不显示数据
    使用bmob后端云中listview如何实现数据显示在第一个item
    安卓如何实现点击一个按钮退出整个程序?
    Python安装与准备
    敏感度——区分平庸和伟大
    fragment中设置点击事件(onclick)使用intent进行通信
    listview的几种简单用法
    Android开发现在是不是该学?
    数据包重放
    Sql注入一种dump所有数据的方法
  • 原文地址:https://www.cnblogs.com/jiqingwu/p/c_sequence_point.html
Copyright © 2011-2022 走看看