C语言的序列点

255 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

序列点

序列点是程序执行的点。在该点上,所有的副作用(可以看上一篇)都在进入下一步之前发生。在C语言中,语句中的分号标记了一个序列点。意思是,在一个语句中,赋值运算符,递增运算符和递减运算符对运算对象做的改变必须在程序执行下一条语句之前完成。任何一个完整表达式的结束也是一个序列点。

完整表达式

所谓完整表达式,就是指这个表达式不是另一个更大表达式的子表达式。例如,表达式语句中的表达式和while循环中的作为测试条件的表达式,都是完整表达式。

序列点好处

序列点有助于分析后缀递增何时发生。例如下面:

while(guests++<10)
printf("%d\n",guests);

对于该例,C语言的初学者认为“先使用值,再递增它”的意思是,在printf()语句中先使用guests,再递增它。但是,表达式guests++<10是一个完整的表达式,因为它是while循环的测试条件,所以该表达式的结束就是一个序列点。因此,C保证了在程序转至执行printf()之前发生过副作用(即:递增guests)。同时,使用后缀形式保证了guests在完成与10的比较后才能进行递增。

例如下面这条语句:y=(4+x++)+(6+x++);

表达式4+x++不是一个完整的表达式,所以C无法保证X在子表达式4+x++求值后立即递增x。这里,完整的表达式是整个赋值表达式语句,分号标记了序列点。所以,C保证了在执行下一条语句之前递增x两次。C并未指明是在对子表达式求值以后递增x,还是对所有表达式求值后再递增x。因此,应避免编写这类语句。