您现在的位置是:网站首页> 新闻快讯> 软件使用 新闻快讯
c语言学习系统
小玉2023-07-05【软件使用】
269人已围观
简介网页链接c语言的副作用和序列点在学习C语言运算符和表达式时,大家对优先级和结合性一定是很熟悉,但是写出代码后,发现还有计算不一致的问题。大多计算

c语言学习系统
最后更新:2023-07-05 04:00:49
推荐指数:
网页链接c语言的副作用和序列点在学习C语言运算符和表达式时,大家对优先级和结合性一定是很熟悉,但是写出代码后,发现还有计算不一致的问题。大多计算不一致问题其实和c语言副作用有关,掌握C语言副作用,你一定会知道怎样编写计算确定的程序,程序也可以很好的移植。先看几个概念:1。引用透明:如果一个表达式(或子表达式)只计算出值而不改变环境,我们就说它是引用透明的,这种表达式早算晚算对其他计算没有影响(不改变计算的环境。当然,它的值可能受到其他计算的影响)。比如:(a+b)*(c+d),无论先计算乘号两边都可以2.副作用:如果一个表达式不仅算出一个值,还修改了环境,就说这个表达式有副作用(因为它多做了额外的事)。比如:a++那么,多个副作用之间的发生顺序是怎样的?C标准规定代码执行过程中的某些时刻是SequencePoint,当到达一个SequencePoint时,在此之前的SideEffect必须全部作用完毕,在此之后的SideEffect必须一个都没发。至于两个SequencePoint之间的多个SideEffect哪个先发生哪个后发生则没有规定,编译器可以任意选择各SideEffect的作用顺序。解释一下就是,在目标的代码里,对同一元素的多次访问(内存的访问)必然通过几段独立代码完成。现代计算机的计算都在寄存器里做,顺序点的作用就是确保在某个时刻这些改变必须反应到随后对同一存储位置的访问中。看看常见顺序点的位置:1.每个完整表达式结束时。完整表达式包括变量初始化表达式,表达式语句,return语句的表达式,以及条件、循环和switch语句的控制表达式(for头部有三个控制表达式)2.运算符&&、||、?:和逗号运算符的第一个运算对象计算之后;3.函数调用中对所有实际参数和函数名表达式(需要调用的函数也可能通过表达式描述)的求值完成之后(进入函数体之前)。4.在一个完整的声明末尾是SequencePoint,所谓完整的声明是指这个声明不是另外一个声明的一部分。比如声明inta[10],b[20];,在a[10]末尾是SequencePoint,在b[20]末尾也是。5.像printf、scanf这种带转换说明的输入/输出库函数,在处理完每一个转换说明相关的输入/输出操作时是一个SequencePoint。6.库函数bsearch和qsort在查找和排序过程中的每一步比较或移动操作之间是一个SequencePoint。标准截图:这样一来,老谭绿皮书上的一个错误就显而易见了,《C程序设计》第三版64页中,有这么一个表达式a+=a-=a*a,在a的初值为12时,该表达式的结果可能是-120也可能是-264.原因就留给各位读者了哈。事实上,如果用gcc的wall选项编译可以看到operation'a'maynotbedefined的警告。正是基于这些原因使得不少公司的类似的笔试题都被专业人士鄙为恶趣味。C/C++语言的做法完全是有意而为,其目的就是允许编译器采用任何求值顺序,使编译器在优化中可以根据需要调整实现表达式求值的指令序列,以得到效率更高的代码。像Java那样严格规定表达式的求值顺序和效果,不仅限制了语言的实现方式,还要求更频繁的内存访问(以实现副作用),这些可能带来可观的效率损失。应该说,在这个问题上,C/C++和Java的选择都贯彻了它们各自的设计原则,各有所获(C/C++潜在的效率,Java更清晰的程序行为)说这么多对我们写代码的指导意义是,在两个SequencePoint之间,同一个变量的值只允许被改变一次。另外,如果在两个SequencePoint之间既要读一个变量的值又要改它的值,只有在读写顺序确定的情况下才可以这么写。举个例子,同样是只改变变量一次,同样是等号左边写,等号右边读,i=i+i是可行的,而a[i++]=i的结果就是未定义的。参考文章,裘宗燕教授的C/C++语言中的表达式求值
很赞哦! (0)
上一篇:乖巧的帆:利雅得新月报价梅西
下一篇:打砖块游戏下载(打砖块 游戏)
相关文章
文章评论
验证码: