在这篇文章中,我们将尝试涵盖许多模棱两可的问题,比如下面的问题。
猜猜下面程序的输出。
// 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" , p); } |
以上所有程序的输出均为 未定义 或 未指明 .不同的编译器和机器的输出可能不同。这就像询问未定义的自动变量的值。
程序1中未定义行为的原因是,运算符“+”没有为其操作数定义标准的求值顺序。可以先执行f1()或f2()。因此,输出可能是“GeeksForgeks”或“ForgeksGeek”。 与运算符“+”类似,大多数其他类似的运算符,如“-”、“/”、“*”、按位和&、按位或|、。。etc没有为其操作数定义标准的求值顺序。
表达式的计算也可能产生副作用。例如,在上面的程序2中,p的最终值是不明确的。根据表达式求值的顺序,如果先执行f1(),则p的值将为55,否则为40。
程序3的输出也未定义。可能是64,72,或者其他什么。子表达式i++会产生副作用,它会修改i的值,这会导致未定义的行为,因为在同一表达式的其他地方也引用了i。
与上述情况不同, 在执行序列中的特定点调用 序列点 之前评估的所有副作用都保证是完整的 A. 序列点 定义计算机程序执行过程中的任何一点,在该点上,可以保证之前评估的所有副作用都已执行,且后续评估的副作用尚未执行。以下是C标准中列出的顺序点:
-以下运算符的第一个操作数的结尾: a) 逻辑与&& b) 逻辑或|| c) 有条件的? d) 逗号,
例如,以下程序的输出保证在所有编译器/机器上都是“Geeksforgeks”。
// Following 3 lines are common in all of the below programs #include <stdio.h> 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/en-us/library/d45c7a5d(v=vs.110)。aspx http://www.open-std.org/jtc1/sc22/wg14/www/docs/n925.htm
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。