在这篇文章中,我们将尝试涵盖许多模棱两可的问题,例如以下内容。
猜猜以下程序的输出。
// PROGRAM 1
#include
int f1() { printf ("Geeks"); return 1;}
int f2() { printf ("forGeeks"); return 1;}
int main()
{
int p = f1() + f2();
return 0;
}
// PROGRAM 2
#include
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
int main()
{
int i = 8;
int p = i++*i++;
printf("%d\n", p);
}
以上所有程序的输出均未定义或未指定。使用不同的编译器和不同的机器,输出可能会有所不同。就像询问未定义的自动变量的值一样。
程序1中行为未定义的原因是,运算符’+’对其操作数没有标准的定义求值顺序。可以先执行f1()或f2()。因此,输出可能是“ GeeksforGeeks”或“ forGeeksGeeks”。
与运算符’+’相似,大多数其他类似的运算符,例如’-‘,’/’,’*’,按位AND&,按位OR |,..等,也没有标准定义的操作数求值顺序。 。
评价表达也可能产生副作用。例如,在上述程序2中,p的最终值是不明确的。根据表达式求值的顺序,如果首先执行f1(),则p的值为55,否则为40。
程序3的输出也未定义。它可能是64、72,或其他。子表达式i ++会产生副作用,它会修改i的值,这会导致不确定的行为,因为在同一表达式的其他地方也引用了i。
与上述情况不同,在执行序列中某些特定的点(称为序列点)上,可以保证先前评估的所有副作用都是完整的。序列点定义了计算机程序执行中可以保证执行之前评估的所有副作用并且尚未执行来自后续评估的副作用的任何点。以下是C标准中列出的顺序点:
—以下运算符的第一个操作数的结尾:
a)逻辑AND &&
b)逻辑或||
c)有条件的?
d)逗号,
例如,在所有编译器/机器上,以下程序的输出保证为“ GeeksforGeeks”。
// Following 3 lines are common in all of the below programs
#include
int f1() { printf ("Geeks"); return 1;}
int f2() { printf ("forGeeks"); 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)退货声明
c)if,switch,while或do-while语句的控制表达式。
d)for语句中的所有三个表达式。
上面的序列点列表是不完整的。我们将在下一篇有关序列点的文章中介绍所有剩余的序列点。
参考:
http://en.wikipedia.org/wiki/Sequence_point
http://c-faq.com/expr/seqpoints.html
http://msdn.microsoft.com/zh-CN/library/d45c7a5d(v=vs.110).aspx
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n925.htm