c语言编程问题求解
#include<stdio.h>fun(int a)
{int b=4;
static int c;
b++;c++;
return(a+b+c);}
void main(){
int a=2,c=3; prentf("%d,%d,%d,”fun(c),fun(a),fun(fun(c)));
}
运行结果为:12,10,16求解题过程
追问:来自手机问问如果是在vc2008下运行能不能告诉我解题过程,这是历年考试真题,谢谢了
追问:来自手机问问如果是在vc2008下运行能不能告诉我解题过程,这是历年考试真题,谢谢了
答案:没有正确答案,C语言没有规定函数各参数的求值顺序,printf("%d,%d,%d",fun(c),fun(a),fun(fun(c)));这一句里fun(c),fun(a),fun(fun(c))的执行顺序在不同的编译器里可能会有不同,所以结果也不同。
改写一下程序方便看执行顺序:
VC2008的结果是12,10,16,因为它选择了fun(fun(c)),fun(a),fun(c)的执行顺序。
lcc win32的结果是9,9,20,因为它选择了fun(c),fun(a),fun(fun(c))的执行顺序。
下面摘自裘宗燕:C/C++ 语言中的表达式求值
少数语言明确规定了运算对象的计算顺序(Java规定从左到右),C/C++ 则有意不予规定,既没有规定大多数二元运算的两个对象的计算顺序(除了&&、|| 和 ,),也没有规定函数参数和被调函数的计算顺序。
为什么人们设计C/C++时不把顺序规定清楚,免去这些麻烦?C/C++ 语言的做法完全是有意而为,其目的就是允许编译器采用任何求值顺序,使编译器在优化中可以根据需要调整实现表达式求值的指令序列,以得到效率更高的代码。像Java那样严格规定表达式的求值顺序和效果,不仅限制了语言的实现方式,还要求更频繁的内存访问(以实现副作用),这些可能带来可观的效率损失。应该说,在这个问题上,C/C++和Java的选择都贯彻了它们各自的设计原则,各有所获(C/C++ 潜在的效率,Java更清晰的程序行为),当然也都有所失。还应该指出,大部分程序设计语言实际上都采用了类似C/C++的规定。
不少书籍在这些问题上有错(包括一些很流行的书)。例如说C/C++ 先算左边(或右边),或者说某个C/C++ 系统先计算某一边。这些说法都是错误的!一个C/C++ 系统可以永远先算左边或永远先算右边,也可以有时先算左边有时先算右边,或在同一表达式里有时先算左边有时先算右边。不同系统可能采用不同的顺序(因为都符合语言标准);同一系统的不同版本完全可以采用不同方式;同一版本在不同优化方式下,在不同位置都可能采用不同顺序。因为这些做法都符合语言规范。在这里还要注意顺序点的问题:即使某一边的表达式先算了,其副作用也可能没有反映到内存,因此对另一边的计算没有影响。
C/C++ 语言的规定告诉我们,任何依赖于特定计算顺序、依赖于在顺序点之间实现修改效果的表达式,其结果都没有保证。程序设计中应该贯彻的规则是:如果在任何“完整表达式”(形成一段由顺序点结束的计算)里存在对同一“变量”的多个引用,那么表达式里就不应该出现对这一“变量”的副作用。否则就不能保证得到预期结果。注意:这里的问题不是在某个系统里试一试的问题,因为我们不可能试验所有可能的表达式组合形式以及所有可能的上下文。这里讨论的是语言,而不是某个实现。总而言之,绝不要写这种表达式,否则我们或早或晚会某种环境中遇到麻烦。你只传递了实参的值,但是在函数中却没有调用