所以说得更清楚,这与我需要指导的家庭作业有关。我不需要代码或任何东西,但这让我发疯,我需要一些澄清。我什至没有问书中的问题。
我有以下代码:
int fun(int *c){
*c += 10;
return *c ;
}
void main(){
int a, b;
a = 10;
b = a + fun(&a);
printf("value of a is %dn", a);
printf("With the function call on the right, ");
printf(" b is: %dn", b);
a = 10;
b = fun(&a) + a;
printf("With the function call on the left, ");
printf(" b is: %dn", b);
}
当我运行它时,我得到"a 的值为 20"和"右侧的函数调用为 40"和"左侧的函数调用为 40
"。我感到困惑的是,我之前有一个非常相似的问题
#include<stdio.h>
int fun(int *k) {
*k += 4;
return 3 * (*k) - 1;
}
void main() {
int i = 10, j = 10, sum1, sum2;
sum1 = (i / 2) + fun(&i);
sum2 = fun(&j) + (j / 2);
printf("%d", sum1);
}
sum1 的答案是 46,sum2 的答案是 48,这在我的脑海中对 codepad.org 编译器的从左到右评估是有意义的。但是在 Pelles C 编译器中,它变成了 48。 您可以看到第一个问题中的代码布局几乎完全相同。
我确实找到了这个链接:在 C 中调用函数之前的参数求值顺序,这似乎解释了这种不一致,但我想确保我的思路不会偏离。那么可以肯定地说,这取决于编译器以及编译器认为最有效的方法吗?
在这两个表达式中
sum1 = (i / 2) + fun(&i);
sum2 = fun(&j) + (j / 2);
您有未指定的行为,因为未指定 +
子表达式的计算顺序。编译器可以根据需要在调用之前或之后自由评估(i/2)
和(j/2)
。
与强制左边求值先于右侧的&&
和||
运算符不同,+
、-
、*
、/
、%
,以及所有按位运算符都允许编译器根据其优化策略选择最方便的求值顺序。这意味着不同的编译器可能会决定以不同的方式评估+
的方面。
从实际角度来看,这意味着您应该在同一表达式中使用具有副作用的表达式不超过一次。您可以重写两个表达式以强制所需的计算顺序,例如
sum1 = i/2;
sum1 += fun(&i);
或
sum2 = sun(&j);
sum2 += j/2;