1. 主页
  2. 文档
  3. C语言教程
  4. C语言其他
  5. C语言中的序列点

C语言中的序列点

在这篇文章中,我们将尝试涵盖许多模棱两可的问题,如下所示。

猜猜以下程序的输出。


// PROGRAM 1
#include <stdio.h>
int f1() { printf ("Geeks"); return 1;}
int f2() { printf ("forGeeks"); return 1;}
int main() 
{ 
int p = f1() + f2(); 
return 0; 
}

// PROGRAM 2
#include <stdio.h>
int x = 20;
int f1() { x = x+10; return x;}
int f2() { x = x-5; return x;}
int main()
{
int p = f1() + f2();
printf ("p = %d", p);
return 0;
}


// PROGRAM 3
#include <stdio.h>
int main()
{
int i = 8;
int p = i++*i++;
printf("%d\n", p);
}

上述所有程序的输出都是undefinedunspecified。不同编译器和不同机器的输出可能不同。这就像询问未定义的自动变量的值。

程序 1 中未定义行为的原因是,运算符 ‘+’ 对其操作数没有标准定义的求值顺序。可以先执行 f1() 或 f2()。所以输出可能是“GeeksforGeeks”或“forGeeksGeeks”。
与运算符 ‘+’ 类似,大多数其他类似的运算符,如 ‘-‘、’/’、’*’、Bitwise AND &、Bitwise OR |、.. 等都没有标准定义的操作数求值顺序.

表达式的评估也可能产生副作用。例如,在上面的程序 2 中,p 的最终值是不明确的。根据表达式求值的顺序,如果 f1() 先执行,则 p 的值为 55,否则为 40。

程序 3 的输出也是未定义的。它可能是 64、72 或其他值。子表达式 i++ 会产生副作用,它会修改 i 的值,这会导致未定义的行为,因为 i 在同一表达式的其他地方也被引用。

与上述情况不同,在称为序列点的执行序列中的某些指定点处,先前评估的所有副作用都保证是完整的序列点定义了计算机程序执行中的任何点,在该点处,可以保证先前评估的所有副作用都已执行,并且尚未执行后续评估的任何副作用。以下是 C 标准中列出的序列点:

— 以下运算符的第一个操作数的结尾:
a) 逻辑与 &&
b) 逻辑或 ||
c) 有条件的?
d) 逗号,

例如,以下程序的输出保证在所有编译器/机器上都是“52cxydhfor52cxydh”。

// Following 3 lines are common in all of the below programs
#include <stdio.h>
int f1() { printf ("52cxydh"); return 1;}
int f2() { printf ("for52cxydh"); return 1;}

// PROGRAM 4
int main() 
{ 
// Since && defines a sequence point after first operand, it is 
// guaranteed that f1() is completed first.
int p = f1() && f2(); 
return 0; 
}

// PROGRAM 5
int main()
{
// Since comma operator defines a sequence point after first operand, it is
// guaranteed that f1() is completed first.
int p = (f1(), f2());
return 0;
}


// PROGRAM 6
int main() 
{ 
// Since ? operator defines a sequence point after first operand, it is 
// guaranteed that f1() is completed first.
int p = f1()? f2(): 3; 
return 0; 
}

— 完整表达式的结尾。此类别包括以下表达式语句
a) 任何以分号结尾的完整语句,例如“a = b;”
b) return 语句
c) if、switch、while 或 do-while 语句的控制表达式。
d) for 语句中的所有三个表达式。

上面的序列点列表是部分的。我们将在下一篇关于序列点的文章中介绍所有剩余的序列点。

 

这篇文章对您有用吗?