回 帖 发 新 帖 刷新版面

主题:[讨论]求证一道编程题的解是否正确

题目:修改下面程序段
#define MAXINT 100
int Calculate(int apple,int orange)
{int peach,lemon;
 peach =0; leamon =0; if(apple<orange){
 peach =orange;}[color=FF0000]else if(orange <= apple){
 peach =apple;}else{peach =MAXINT;lemon=MAXINT;
 }if(lemon!=MAXINT){return(peach);}}[/color]
出自Kruse的《数据结构与程序设计—c语言(第二版)》练习(2)a

本人修改如下
#defined MAXINT 100
int Calulate(int apple,int orange)
{
    int peach=0,lemon=0;
    if (apple < orange)     peach =orange;
    else          peach =apple;
    return (peach)    
}

我这样改是否正确,包括格式和算法。
希望大家能给指正,并说明道理。谢谢

回复列表 (共2个回复)

沙发

楼主的代码里面,有几处字都打错了。

“apple < orange”与“orange <= apple”两个条件是互补的,因此第一段代码中最后的那个“else”分支是永远不会执行到。于是,局部变量leamon的值始终为零。lemon!=MAXINT成立,返回peach的值,也就是apple和orange之中的较大者。

修改后的代码也达到了同样的目的。我用Visual C++ 2008 Express实验,代码修改前后,产生的汇编代码一模一样,没有任何区别。

注意修改后的代码中,lemon这个变量其实没有用到,可以省去。其实还可以更简单:
int Calculate(int apple, int orange)
{
    if (apple < orange) return orange;
    else                return apple;
}

楼主可能会想,如果硬件故障,导致“apple < orange”与“orange <= apple”两个条件同时不成立,于是第一段代码会进入else的那个分支。导致lemon!=MAXINT不成立,于是return语句不被执行。但这是不会发生的。C/C++有一个volatile关键字,用这个关键字修饰的变量,随时可能变化,于是可能出现前面说的这种情况。但是现在apple和orange并没有用volatile修饰,所以编译器认为,除非我们的代码修改,否则apple和orange的值永远不会发生变化。所以编译器认为即使发生硬件故障,仍然不会进入那个else分支,于是无论我们在那个else分支里面写了多少代码,它都是永远不可能被执行的,最终产生汇编代码时,这些内容会被删除掉。最终形成的效果就是,两段代码产生的汇编指令一模一样。


附上汇编指令如下:
    printf("%d\n", Calculate(apple, orange));
00401018  mov         eax,dword ptr [esp+0Ch] 
0040101C  mov         ecx,dword ptr [esp+10h] 
00401020  add         esp,0Ch 
00401023  cmp         eax,ecx 
00401025  jge         main+29h (401029h) 
00401027  mov         eax,ecx 
00401029  push        eax  
0040102A  push        offset string "%d\n" (4020FCh) 
0040102F  call        dword ptr [__imp__printf (40209Ch)]

板凳

顶一下把

我来回复

您尚未登录,请登录后再回复。点此登录或注册