abs(1) == 1?

lifanxi 2003-05-27 11:38:16
这是个同学让我帮忙解决的研究生入学复试题。
看下面的程序:
int fact()
{
static int i=5;
if(i==0)return 1;
else{
i=i-1;
return (i+abs(1))*fact();
}
}
main()
{
printf("factor of 5=%d\n",fact());
}
在TC下,运行结果是factor of 5=120。
但如果把fact()中的abs(1)改成1,运行结果是factor of 5=1!
问题就是为什么会这样。
原因我已经找到了,如果写abs(1),编译器先算(i+abs(1))再乘fact(),所以是正常的结果120。如果写成1,编译器会先算fact(),等fact()最终返回时,i的值已经是0了,所以最终就变成1*1*1*1*1,答案是1。
我想问的是:TC这样处理是不是有它的道理?如果按标准C来说,对这样的情况是否有明确规定,还是由编译器自己处理?
这个问题好像有点无聊,不过希望大家能来谈谈看法。谢谢!
...全文
224 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
Meyer 2003-05-29
  • 打赏
  • 举报
回复
对于 && 和 || 两个二元逻辑操作符,C++ 规定从左到右求值

但对于 其它的二员运算符 左右两边的子表达式,先求那个确实是没有定义
结果为 1 ,也是正常的。

这个程序写的真的很 LB , 用什么 static 变量?
liu_feng_fly 2003-05-29
  • 打赏
  • 举报
回复
哦,我举的例子确实错了:)
i_jianyong 2003-05-29
  • 打赏
  • 举报
回复
对于 && 和 || 两个二元逻辑操作符,C++ 规定从左到右求值,因此我们可以安全地运用“短路判断”,但对于除 && 和 || 之外所有二元操作符,C++ 并没有统一规定求值顺序,而是取决于个编译器。

参见C++ Primer中文版(潘爱民)P.121, 122
晨星 2003-05-28
  • 打赏
  • 举报
回复
没什么道理,表达式是从左往右求值的。但有优先级问题,函数优先级最高,乘除比加减高,等等。
dragoncircle 2003-05-28
  • 打赏
  • 举报
回复
短路判断不能象darkay_Lee那样理解,短路判断只是要求,如果某一表达式的值已经能决定整个表达式的值,则其他表达式就不用再计算了,并没有说,一定要从左求到右。就是从右到左,也可以进行短路判断的嘛。
liu_feng_fly 2003-05-28
  • 打赏
  • 举报
回复
同一个表达式里面的各个子表达式的评估求值的顺序是未定义的,这不是编译器的错,只能怪程序员了:)
xiaoyunet 2003-05-28
  • 打赏
  • 举报
回复
应该是编译器的bug吧,还当作宝来考学生,靠。
flab_lwq 2003-05-28
  • 打赏
  • 举报
回复
学习
晨星 2003-05-28
  • 打赏
  • 举报
回复
还有一个问题,有的头文件里,abs是个宏,有的头文件里,则是一个函数,宏和函数的运行结果肯定不一样。
Darkay_Lee 2003-05-28
  • 打赏
  • 举报
回复
反对 liu_feng_fly(笑看风云 搏击苍穹 衔日月)
无论C还是C++
if(exp1 && exp2)
从来就是先求exp1再求exp2的。否则“短路判断”从何而来。
lbaby 2003-05-28
  • 打赏
  • 举报
回复
啊?
这样的题是用来考研的?
lifanxi 2003-05-28
  • 打赏
  • 举报
回复
谁有C语言的ISO标准吗?能不能给我发一份?谢谢!lifanxi@263.net
我可以用C++的ISO 14882与他交换:)
lifanxi 2003-05-28
  • 打赏
  • 举报
回复
不知道对于C语言来说怎么样,在C++中,14882明确说,对于&&来说,一定是从左往右求值的,所以if ((p!=0) && strcpy(p,"hello"))在C++是绝对安全的。
14882说:
Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
dragonlw 2003-05-28
  • 打赏
  • 举报
回复
中国科学院软件研究所的考题吧!可能是99年的
liu_feng_fly 2003-05-28
  • 打赏
  • 举报
回复
to ckacka:
因为i是static的变量
return (i+abs(1))*fact();
是先计算i+abs(1)还是先计算fact()是不确定的。而fact里面又更改了i的值,所以结果是不确定的。
就好象
char* p;
...
if((p != NULL) && strcpy(p,"hello"))
上面这句本意是要保证p是长度不为0的字符串的指针,然后拷贝一些字符串到p里面,但是他是有问题的,因为c++并没有规定对于编译器必须先求p!=NULL的值,也就是说可能先执行strcpy(p,"hello"),这样就造成了错误。
对于
return (i+abs(1))*fact();
这个表达式,如果先求fact()就会有问题了
flab_lwq 2003-05-28
  • 打赏
  • 举报
回复
有个括号的话,不管(i+abs(1))还是(i+1)都应该从左算到右吧?
ckacka 2003-05-28
  • 打赏
  • 举报
回复
liu_feng_fly(笑看风云 搏击苍穹 衔日月)

按照你这么说
return (i+abs(1))*fact();
应该有怎样的顺序呢

我简单地分析了一下,得到1好像是不对的

不信你自己试试 ^_^
ckacka 2003-05-28
  • 打赏
  • 举报
回复
不知道各位是怎么看的?
maybe it is a bug ^_^
ckacka 2003-05-28
  • 打赏
  • 举报
回复
borland的编译器都是这样的,结果都是这样的规律
而ms的就不一样,都是120,你试试
dev-cpp也是120

所以我觉得这应该是他们采用的语法分析的方法上面的问题

不过我觉得都应该是120才对,得到1可能是有问题的
cloudtarget 2003-05-28
  • 打赏
  • 举报
回复
编译器???

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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