可能重复:
Parameter evaluation order before a function calling in C
order of evaluation of function parameters
以下代码的输出结果如何:
n=5;
printf("%d %d\n", ++n, power(2, n));
输出= 32
不应该输出2 ^ 6 = 64?
不同的编译器会给出不同的结果吗?
答案 0 :(得分:6)
函数参数的评估顺序是未指定。编译器可以按任何顺序计算参数,但它必须以某种特定顺序执行(因此这里没有 undefined 行为)。输出可以是32或64。
UPD:这是错误的,这里有UB,请参阅here。
答案 1 :(得分:1)
与其他答案相反,代码可能确实表现出未定义的行为。
如上所述,函数参数的评估顺序在C中未指定。在您的程序中,您有一个由多个子表达式组成的表达式:
ex0(ex1, ex2, ex3(ex4, ex5));
这些子表达式之间只有部分排序:ex4
和ex5
显然必须先评估ex3
,ex1
,ex2
,ex3
必须在评估ex0
之前进行评估。除此之外,子表达式的评估顺序是未指定的,由编译器决定评估子表达式的顺序。
某些有效的评估订单会产生未定义的行为。例如,如果在++n
之前评估power(2, n)
,则结果是未定义的:在评估函数的所有参数之后但在之前或之间存在一个序列点,以及C语言标准非常清楚地说明(C99§6.5/ 2;强调我的):
在前一个和下一个序列点之间,一个对象的存储值最多只能通过表达式的一次修改一次。此外,先前的值应该是只读的,以确定要存储的值。
如果首先评估++n
,则会违反此规则,因为n
修改了++n
,而n
调用了power(2, n)
而没有这两个步骤之间的序列点。
展示未定义行为的程序可能会产生任何结果:它可能会崩溃,可能会打印出意外的答案,或者它可能看起来像您期望的那样工作。由于您的程序可能表现出未定义的行为,因此很难确切地讨论您看到的实际行为。最好避免编写可能(或更糟,实际上)表现出未定义行为的程序。
答案 2 :(得分:0)
你的力量功能包含什么?我刚检查了C数学库的pow功能。我不得不把它投到< int>像这样;
#include <cstdio>
#include <cmath>
using namespace std;
int main () {
int n=5;
printf("%d %d\n", ++n, (int)pow(2.0, n));
return 0;
}
输出:6 64
我使用的是Microsoft Compiler(由Visual Studio使用)。希望它有所帮助。