C语言十分令人不解的...?(100分)

  • 主题发起人 主题发起人 张利中
  • 开始时间 开始时间

张利中

Unregistered / Unconfirmed
GUEST, unregistred user!
有下面两个C程序:
1. main()
{ int x=5;
int y;
y=++x*--x;
printf("%d", y);
}
2. main()
{ int x=5;
printf("%d", ++x*--x);
}
上机运行,第一个题输出25, 第二个题输出30 .不明白为什么?
请各位指教!
 
你搞错了吧?两种方法输出结果一样,都是25.

我用的是Dev C++
 
怎么会不一样呢?
 
我用TC2试过了,确实如此,等于25还好理解,等于30就没办法理解了。
 
这可能是不同的编译器所造成的!我用VC,C++ BUILDER,TURBO C试过了!
VC输出的都是25,
而C++ BUILDER,TURBO C输出的一个是25,一个是30;
所以在刚开始学习编程时尽量要养成不要把代码写得太简节!
那样写出的代码难懂又易出错!
 
我刚才也用C++ BUILDER试了一下,也是25和30,谁能解释,我加分。
 
用BCB5也是得出25和30。也许是printf多加了一遍。在任何情况下我都会用前一种方法
来实现。
我觉得研究这个没意思,现在你做程序还用printf来输出吗?++x*--xx这样的算法会出现
在实用的程序中吗?
 
不用printf来输出难道就不能研究这个问题吗?++x*--xx这样的算法当然不会出现在实用的
程序中,但它可以帮助我们了解C编译器到底是怎么工作的,以后在实际工作中就可以避免
出现类似的错误。
 
我在Turbo c下调试, 结果分别是25和30;
在VC下调试, 结果都为25.
如果以VC的编译器为准, 那么针对表达式++x*--x而言,
是从左向右计算,还是从右向左计算?即25是如何
得到?请各位说得详细些!
 
这好象跟从左到右还是从右到左没有什么关系啊,而是好象只加了,没有减,才会出现
5*6=30.
 
这个程序有意义吗?
你可以分几步来完成!
 
我猜printf("%d", ++x*--x);是++x(6)*--x(6-1=5)
最后6*5=30,是不是和printf 的计算方式有关。
 
为什么不去看CPU窗口呢?看了不就全明白了...
如果25是符合C语言编译器标准的结果,那么30的原因是Borland编译器传参数的时候使用了寄存器。
换句话说,如果Borland编译器没有错,那么“表达式”这个概念在语句中与在参数中有不同的含义(这似乎不太可信)

按我个人的观点,思维正常的人会认为30是标准答案,而25则是C语言副作用发挥到极点的充分证明。
因此,我不知道应该说这是谁的问题,只能说一句 C语言确实不怎么样! :-)
 
>>“思维正常的人会认为30是标准答案”
呵呵,那MS那帮开发VC的家伙都是思维不正常的罗?

不许你说C语言的坏话,虽然现在已经好少用C了,但它可是我的初恋情人,再怎么样都是我
的最爱。 :)
 
>>呵呵,那MS那帮开发VC的家伙都是思维不正常的罗?
我可没这么说呀!不要忘了,Borland编译器也有一种情况得25 :-)
这根本不是Borland还是M$的问题,这是C语言的问题。

我是说C语言这种明显的副作用,当然不符合正常人的逻辑思维方式,仅此而已。
关键在于“表达式”这一概念怎样理解,你想想就明白了...
这个例子说明,C语言当中连表达式的概念都可能产生歧义,还说不是... :-)
 
无聊的把戏!应该过时了。
大家应该写让人能读得懂的程序。
大家应该写有确切含义的程序。
表达式的概念如果可能产生歧义,应该用括号表明其优先级;
同志们,这就是中国人与印度人的差距所在!
 
to htw:
你说的观点我都同意,也都是我一贯提倡的...

不过你用在这个问题上是没有找准目标 :-)
这个问题并非任何游戏,而是反映C语言的“问题”

>>表达式的概念如果可能产生歧义,应该用括号表明其优先级;
问题恰恰就在这里,否则也不是问题了 -- 加了括号没任何影响,这个问题与优先级毫无关系...
 
这种现象的出现,根本原因是编译器在编译程序时处理问题的“思路”不同(更确切的说:编译器的作者
的思路的不同)。

问题1:
y = ++x * --x
编译器“认为”等号右边是一个表达式(记住:是一个表达式),然后将这个表达式分解,
先将乘号左右的部分算出来,再将每一部分乘起来,这样步骤如下:
(1) ++x = ++5 = 6 (x是6)
(2) --x = --6 = 5 (x是5)
(3) 5 * 5 = 25 (结果是25)
若将 y = ++x * --x 变成 y = --x * ++x 结果一样。
又如:y = (++x) + (++x) + (++x); 先将5加3次1
24 = 8 + 8 + 8;
问题2:
printf("%d", ++x*--x);
编译器认为其中的“++x*--x”不是一个表达式,而是++x是一个,--x是一个,
所以步骤如下:
(1) ++x = ++5 = 6 (第一个表达式是6)
(2) --y = --6 = 5 (第一个表达式是5)
(3) 6 * 5 = 30
若将printf("%d", ++x*--x);变成printf("%d", --x*++x);则结果为4 * 5 = 20
又如printf("%d", (++x) + (++x) + (++x));
21 6 + 7 + 8
结论:编译器“认为”y = ++x * --x 是一个表达式 ;而printf("%d", ++x*--x);是两个
表达式。(或许在概念上不应该说是几个表达式,但就是这个意思)
 
>>只能说一句 C语言确实不怎么样!
>>这根本不是Borland还是M$的问题,这是C语言的问题。
这两句话未免太过分了!!

我的看法是:就我目前的水平,我认为我没有资格谈论C语言好还是不好。我只想摆一个事实:
长期以来,不论是Microsoft、IBM......这样的大公司,还是一些小公司,应用的最多的是C/C++,
绝大部分的系统软件都是用C/C++开发的,这些人不会个个都是傻瓜吧!!!!
 

Similar threads

D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
670
import
I
后退
顶部