关于C语言的副作用和序列点~

******副作用:

     指的是对数据对象(http://blog.csdn.net/qq_37385726/article/details/62896617)或文件的修改。

       对于计算机来说,函数也好,表达式也好,语句也好(关于什么是表达式,什么是语句请戳:http://blog.csdn.net/qq_37385726/article/details/62897923)它们的主要目的就是返回值,但是对于人来说,调用函数,写语句,写表达式的主要目的却是利用它的副作用。

     eg.关于a=3+7这个表达式,计算机的主要目的是它的返回值,即左值的值10,但是我们人的主要目的却是计算机称为的副作用,即将10赋给变量a.


******序列点:

指的是程序执行的点,在该点上,所有的副作用都在进入下一步之前发生。

那么哪些符号会生成序列点呢?

","会生成序列点。

","用于把多条语句拼接成一条语句。 例如:

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。

还有“一个完整的表达式的结束”也是序列点

一个完整的表达式的结束:指的是这个表达式不是另一个更大的表达式的子语句。




===================================================================================

有了上面关于序列点的只是,我们就不难理解以下的这种情况了。


eg.y=(x++)+(x++);   

这个是一个未定义行为,因为虽然自增的优先级被规定为大于+,但是计算机并没有规

定到底先执行哪一个x++,这就带来了一个未定义的问题,我们知道一个完整的表达式

的结束是一个序列点,也就是对于这个表达式而言,(x++)+(x++)是要在它的末尾才

是这个语句开始执行的地方,所以你不知道计算机是在执行了哪一个x++后再执行下一

个,又或者说是先用原来的x以后,再对这个x进行两次的自增,这就是我们所说的未定

义行为。


还有很多这样的例子:num*num++  这就是未定义的,计算机没有指定先执行哪一个

子表达式,所以就带来了像上面所说的未定义行为的问题。



     



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值