是否存在"序列点"问题,例如"int a = 4,*ptr =&a;" 或"x + = 4,y = x*2;"?

Rüp*_*ure 6 c sequence-points

我对整个序列点的理解是基本的.我所拥有的只是一些粗略直观的想法,"一旦遇到序列点,我们就可以确定先前评估的所有副作用都已完成".我还读到,在语句中printf("%d",a++,++a,a++),行为未定义,因为逗号不表示序列点,而分号则表示.因此,我觉得一个非常严谨和确凿的答案对我有很大帮助,而不是通过直觉猜测和思考.

C语言中的以下类型的语句也是安全可靠的:

int a=4,*ptr=&a;  //Statement 1

x+=4,y=x*2;  //Statement 2  (Assume x and y are integer variables)
Run Code Online (Sandbox Code Playgroud)

如果有,怎么样?特别是在第二种情况下,如果逗号不是一个序列点,那么在我们在赋值中使用它之前,我们怎么能确定它x是否增加了?对于第一个语句,在分配地址之前,如何确定已初始化并分配内存?我是否应该安全地使用以下内容:4y=x*2aptr

int a=4,*ptr;
ptr=&a;
Run Code Online (Sandbox Code Playgroud)

x+=4;
y=x*2;
Run Code Online (Sandbox Code Playgroud)

编辑我对逗号运算符的理解告诉我这些语句是安全的.但是在阅读了关于序列点以及类似事物printf("%d",a++,++a,a++)未定义之后,我有了第二个想法.

caf*_*caf 12

在函数调用中分隔函数参数的逗号不是逗号运算符 - 它只是标点符号,恰好与逗号运算符拼写相同.在评估不同的函数参数之间没有序列点,所以这就是你在这种情况下得到UB的原因.

另一方面,在你的表达中:

x+=4,y=x*2;
Run Code Online (Sandbox Code Playgroud)

这里的逗号一个逗号运算符,它引入了一个序列点; 没有UB.

在声明中,声明符之间的逗号也不是逗号运算符; 但是,完整声明符的结尾(声明符不是另一个声明符的一部分)确实引入了一个序列点,所以声明如下:

int a = 2, b = a + 1;
Run Code Online (Sandbox Code Playgroud)

不是UB.