cdn网站网络加速器,漳州城乡和建设局网站,域名查询138,做网站建设价格C语言中复杂表达式的求值顺序
num (5 2) * (9 * 6);如果我问你#xff1a;上面的c程序在执行的时候到底是先算#xff08;5 2#xff09;还是#xff08;9 * 6#xff09;#xff1f;你会怎么回答#xff1f;
无非就两种#xff1a;先算#xff08;5 2#xff…C语言中复杂表达式的求值顺序
num (5 2) * (9 * 6);如果我问你上面的c程序在执行的时候到底是先算5 2还是9 * 6你会怎么回答
无非就两种先算5 2或者先算9 * 6对吧那么我来告诉你这两种结果都不对答案是不确定你应该先问编译器。
副作用和序列点
在解释上面的概念之前我们先来介绍两个专业术语副作用、序列点
副作用
副作用side effect是指对数据对象或文件的修改。 例如
states 50;它的副作用是将变量的值设置为50。
看起来副作用更像是主要目的其实并不是。从C语言的角度来看上面的代码的主要目的是对表达式求值。 给出4 6C会对齐求值得到10同理给出states 50;C语言会对其进行求值得到50。 在C语言的眼里上面的程序更像是这样的
(states 50);类似的printf函数显示的信息其实是它的副作用printf的返回值是待显示字符的个数也就是放入输出缓冲区字符的个数不懂缓冲区的可以看我的这篇文章你真的理解printf函数吗
序列点
序列点sequence point是程序执行的点在这个点上所有的副作用都会在进入下一步之前发生。语句中的分号标记了一个序列点。 分号的意思是在这个语句之前赋值运算符、递增运算符和递减运算符对运算对象做的改变必须在程序执行下一条语句之前完成。 求值顺序
C把先计算哪一个部分的决定权留给编译器的设计者以便针对特定系统优化设计。 也就是说对于开始的那个程序哪一段表达式先被计算是不确定的。
但是对于逻辑运算是个例外。
在C语言中保证逻辑表达式的求值顺序是从左往右。和||都是序列点所以一个程序在从一个运算对象执行到下一个运算对象之前所有的副作用都会生效。
并且重要的一点是C一旦发现某个元素让表达式无效便立即停止求值。
有了上面的规则才能写出下面的代码
while ((c getchar()) ! c ! \n);在上面的代码中读取字符直到遇到第一个空格或者换行符停止需要注意的是如果没有上面的规则c ! \n这个语句就有可能在c getchar()之前执行了这样一来就不能保证语义的正确性了。