帮我看看 下面的程序

CppPrimer 2003-08-22 04:40:51

void __fastcall TForm1::Button1Click(TObject *Sender)
{


ShowMessage(AnsiString(fact()));

}
//---------------------------------------------------------------------------
int fact()
{
static i = 5;
if(i== 0)
{
return 1;
}
else {
i=i-1;

return(( i+abs(1))*fact());

}
}
为什么把abs(1)换成1 返回值就变了呢
而我在vc和java里编译都没有改变啊
...全文
85 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
jishiping 2003-08-26
  • 打赏
  • 举报
回复
还记得小学四年级时,我门的体育老师,是我们学校的教导主任(5年级的数学老师)。有一
次体育课下雨,他就给我们讲高斯的故事,就是那个 1+2+3+4+...+99+100=? 的故事。讲完
之后,他又举了一个例子,10+11+...+49+50=? ,让我们学生回答。当时他的答案是:(10+
50)*(50-10)/2=60*40/2=1200,当时我就指出不对,应该是(10+50)*(50-10+1)/2=60*41/2
(其实就是有多少个数字的问题)。可是老师当时还是没有接受我的答案(也许是面子的问
题吧)。但是我的心里,一直认为我是对的,老师是错的。

我的意思就是,不要认为老师讲的都是对的,教科书(参考书)上讲的都是对的。我学习编
程,就是自学的。我看的第一本C语言的书,是浙江大学的一个老师(可能是教授)写的,可
是上面讲的,我当时一样认为,上面有一些错误(不是很多)。只要是人,都会犯错的。但
是研究生的入学考试的题目,我认为应该是有很多老师把关审核的,不应该所有的人都犯这
样的错误。一个人犯错是可以理解的,那么多人犯错,我认为就不正常了。除非这个试卷,
是一个人出的,也是他自己审核的,没有其他老师参与。可是作为研究生入学考试,如果是
这样的话,你又怎么想呢?我就不多说了。
jishiping 2003-08-26
  • 打赏
  • 举报
回复
道理我已经说了,但是可以明确的说,这是一道典型的错题。
jishiping 2003-08-26
  • 打赏
  • 举报
回复
我的意思,楼主还不明白么。不要以为是考研的题目,就一定是正确的。对于全国卷来说,
把关的人会比较多,出现错误的概率比较低。对于学校出的试卷,把关的人,肯定没有全国
卷把关的人多,出现错误的概率会稍微大一些。即使是以前的全国高考卷,也曾经发生过错
题的。 我的意思就是,试卷也可能出错。

另外,“为什么把abs(1)换成1 返回值就变了呢,而我在vc和java里编译都没有改变啊”,
我已经说了,和编译器有关。正如你自己说的,“在vc和java里编译都没有改变啊”,只是
在Borland的编译器里,返回值会改变,这就说明Borland的编译器,在C语言标准没有明确规
定的情况下,对于表达式的处理次序,和VC的编译器不同。对于乘号两边的表达式,VC简单
的从左到右计算,而BCB不是这么简单,它会同时判断表达式的两边内部的表达式的情况,来
决定先计算哪个表达式。如果是(i+abs(1))*fact(),因为乘号*左右两边都有函数,所以BCB
从左到右计算,如果是(i+1)*fact(),因为左边是简单的加法,右边是函数,BCB就先计算函
数的表达式。因为C语言本身没有对此作明确的规定,所以编译器怎么处理,都不存在错误的
问题。

不是我不去研究题目,而是题目本身有问题,不用去研究他的结果(以及为什么)。可是你
非要我说,我就说给你听好了。
CppPrimer 2003-08-26
  • 打赏
  • 举报
回复
http://www.cer.net/article/20010912/3001181.shtml

原题我已经贴出来 你自己去看吧

或者真的是偶没说清楚

jishiping 2003-08-26
  • 打赏
  • 举报
回复
或许,本来的考研题目,原意不是楼主说的,可是被楼主断章取义后,变味了。
CppPrimer 2003-08-26
  • 打赏
  • 举报
回复
hehe 不知道传闻中的季老大是在挤兑我 还是怎么地

原题目我已经贴出来

你可以自己去看

一味的批判我 不如去研究一下题目
jishiping 2003-08-26
  • 打赏
  • 举报
回复
“hehe 各位,我是来找人解决问题的”
我已经说了,出这个这个题目的人,实在是水平太差了,自己钻牛角尖,研究一些没有实际
意义的问题,同时也想让自己的学生和他一样。
(除非这道题的答案就是:没有确切的答案,和编译器有关,可能为1,也可能为120)

“既然认定是编译器的问题 那么谁可以从编译的角度来讨论一下程序的运行过程呢”
不是编译器的问题,而是和编译器有关。不同的编译器有不同的答案(1或者120)。

“这道题的确是98年中科院的入学考试题,我只是看到觉得比较有意思”
恕我孤陋寡闻,“中科院”是什么?是“中国科学院”吗?“中国科学院”下面也有研究生
班吗?
TR@SOE 2003-08-26
  • 打赏
  • 举报
回复
我看了这个题目,我的理解是,这个题目要求你描述出一种编译机制,在这种机制下,i+abs(1)能得到正确的结果而i+1得不到。

这就不是讨论现有的C/C++编译器的编译体系的问题了,而是要求考生为这个机制作一个合理的解释。那么上面JSP说的已经足够了,只要稍微修改一下就可以了。呵呵。
CppPrimer 2003-08-26
  • 打赏
  • 举报
回复
http://www.cer.net/article/20010912/3001181.shtml

这里有原题 可以去看看 :)
CppPrimer 2003-08-26
  • 打赏
  • 举报
回复
hehe 各位,我是来找人解决问题的
既然认定是编译器的问题 那么谁可以从编译的角度来讨论一下程序的运行过程呢

再次重申一下 :这道题的确是98年中科院的入学考试题,我只是看到觉得比较有意思

希望和大家讨论一下
3x
dongyangzong 2003-08-25
  • 打赏
  • 举报
回复
编程序应该忌讳使用晦涩的语句,给调试带来多大的麻烦。现在都讲究可读性、可移植性。我很少使用容易引起歧义的语句,比如:a=c++,a=++c等。
jishiping 2003-08-25
  • 打赏
  • 举报
回复
“可是如果用vc和jbuilder编译 结果都是120啊”

我想出这道考研题目的老师,也就是用VC测试的结果,得到的答案是120,所以就认定这道
题目的答案就是120吧。我已经说了,这和编译器有关(这儿没有正确的结果,只有错误的
题目)。不是因为有2家编译器的结果是120,而只有1个编译器的结果不是120,就说明120
是正确的结果。这方面的例子,在科学发展史上,实在太多了。同时,我也奉劝各位同学,
不要以为老师讲的,都是正确的。
jishiping 2003-08-25
  • 打赏
  • 举报
回复
"是一道98年考研的题目"

出这道考研题目的老师见鬼去吧。我不敢相信这竟然还是考研的题目。现在的学生的编程水
平越来越差了,连老师的水平也是越来越差了。如果谁因为这是考研的题目,就认定这道题
目的答案就是120,那么我也无话可说了。为什么现在学校里教出来的学生,编程水平越来越
差,我想和学校老师的水平、教学方式大有关系。出这样的题目,一是说明老师的水平太差
二是说明老师就喜欢钻一些稀奇古怪、没有任何实用意义的问题(有这样写求阶乘的函数吗
)。 最后我还想知道,是哪个学校出的这道题?真是丢人现眼啊!
CppPrimer 2003-08-25
  • 打赏
  • 举报
回复
可是如果用vc和jbuilder编译 结果都是120啊

呵呵

不是考大家 是因为这个问题我也搞不清楚 想问问大家
是一道98年考研的题目
大家研究一下
chen_czf 2003-08-25
  • 打赏
  • 举报
回复
顶。楼上老大说得有道理。
TR@SOE 2003-08-25
  • 打赏
  • 举报
回复
对不起,上面说的有些问题。

如果是考研时本身出这样的一个题目:请用递归和静态变量求5的阶乘,那我无话可说。

但是如果是哪本狗屁不通的参考书里把贴主的代码贴出来作为标准代码,那么就不是出题的老师有问题(虽然还是有些小问题),而是出书编答案的人该杀了。

TR@SOE 2003-08-25
  • 打赏
  • 举报
回复
JSP老大说的很对。这个程序,如果只是从程序本身来看,其结果是和编译器对程序中函数调用如何优化相关的。

例如,随便再举个例子。以下代码会显示什么结果?

void main()
{
int a;
printf ("a=%d",a);
}

有些编译器会自作聪明的将a=0,而有些编译器不做这个工作,因此a会是一个随机数。

我不能说编译器好不好,也不说代码好不好。只能说,如果有人这样来出题目就是太无聊了。

回到你的问题。如果是要求阶乘,那么递归算法不是这么写的;如果是要考静态变量,也不用如此出题。老师有问题。

再顺便说一句,如果研究生就考这样的题目,我看这样的研究生不考也罢。我在91年读大三的时候,程序设计水平就已经不止这点水平了。
chen1320 2003-08-22
  • 打赏
  • 举报
回复
学习
jishiping 2003-08-22
  • 打赏
  • 举报
回复
因为 i 是静态变量,所以表达式 (i+abs(1))*fact() 中,先计算前面的(i+abs(1)),还是
先计算后面的fact(),得到的答案就是不同的。先计算后面的fact(),最后的答案就是1。如
果是先计算前面的(i+abs(1)),得到的最后答案就是120。而应该先计算前面的表达式,还是
先计算后面的表达式,C语言并没有明确的规定,所以这个就在于编译器自己定的规则了,不
同的编译器,定的规则也就可能不同,因而最后的答案就不对。 所以,最后的答案就是,
这样的程序写法有问题,不应该使用这样的写法。退一步说,无论使用哪个编译器,第二次
调用 fact() 这个函数时,得到的答案始终是1,和第一次的答案就可能不一样了,这也就说
明这种写法本身是有问题的写法。
pcclever 2003-08-22
  • 打赏
  • 举报
回复
楼上的石头,这确实是个问题,你把楼主的代码直接copy到相应的地方,好像是有这个问题,任何东西都不定义,用abs(1)就是120,用1就是1,纳闷中...
加载更多回复(6)

13,822

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧