副作用 (side effect)
副作用是指对数据对象或文件的修改.
对于表达式来说, 主要作用是求表达式的值, 求值之外产生的其他所有效果均为副作用.
如函数调用表达式 printf("hello\n");
求出显示的字符的个数是主要作用, 显示字符是副作用, 赋值表达式语句 a = 9;
主要作用是求表达式的值, 副作用是改变 a
的值, 即给 a
赋值. 再如递减运算符 a--;
副作用是将 a
的值减 1.
程序示例:
#include<stdio.h>
int main(void)
{
int a = 10;
printf("a++ = %d\n", a++);
printf("a = %d\n", a);
a = 10;
printf("++a = %d\n", ++a);
printf("a = %d\n", a);
return 0;
}
程序结果:
a++ = 10
a = 11
++a = 11
a = 11
a++
和 ++a
的副作用都是将a的值加一,但 a++
这个表达式本身的值是 a 递增前的值,++a
这个表达式本身的值是 a 递增后的值。
序列点 (sequence point)
序列点是执行程序的点, 在该点上, 所有的副作用都在进入下一步之前发生.
序列点有: 完整表达式 (full expression), 表示语句结束的分号, 逻辑运算符 && 和 ||, 逗号运算符.
程序执行到序列点时, 序列点之前的所有副作用全部发生, 然后接着执行序列点之后的程序.
完整表达式指: 该表达式不是另一个更大的表达式的子表达式.
完整表达式有: 表达式语句中的表达式, while 循环中作为测试条件的表达式, for 循环的圆括号内的每一个表达式.
下面的表达式是错误的:
y = (4 + x++) + (6 + x++);
这里 (4 + x++)
和 (6 + x++)
是子表达式. 无法确定是先计算哪个子表达式, 也无法确定何时递增 x. 因此是错误的.