自加自减

linyjing 2002-04-20 11:57:35
在如下程序中
1)
main
{int i=3;
printf ("i=%d,j=%d,i=%d\n",i,(表达式),i);}

2)
main
(int i=3,j;
j=(表达式);
printf ("i=%d,j=%d,i=%d\n",i,j,i);}
结果在TC与VC中不同,1)和2)也不同,有无比较基本的规律,而不是都分别讨论。
如在TC中1)当表达式=(i++)+(++i)+(i--)*(--i)时,先算加法;而当表达式为
(++i)+(i++)+(i--)*(--i)*(++i)时却先算乘法?
在加减中,TC1)一律是集中执行;2)分别逐步执行;
VC中1)与2) j 值相同,同时运算的两项i值同。
...全文
67 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Yardwand 2002-04-21
  • 打赏
  • 举报
回复
对不起,我多嘴了。

希望对你有帮助!
Yardwand 2002-04-21
  • 打赏
  • 举报
回复
现在详细说一下:

先讲一下大多数c编译器中对++和其他运算符的区别。
在一般的二维运算符处理时,其结果将被加入堆栈。如3+4+5,处理时3+4的结果被加入堆栈,然后在用堆栈中的结果7和后面的5相加。但是,在处理++i的时候有所不同。在遇到++i时,并不从堆栈中取出结果来运算,而是通过&i取出i的地址,然后对该地址的内容直接加一。这种处理的来由是因为在IBMPC中,有一条机器语言恰好是对某一变量值加一。为了提高处理速度,在c的处理中,遇到++i之类的处理就直接使用了该语句。其处理并不通过堆栈完成,所以在++i前后的处理,并不会对堆栈中的变量发生变化,也不会引起其他的变量改变。

在弄明白了++i的处理后,再让我们看看运算符实际是如何处理的。
学过编译原理的朋友应该知道,在对某一语言进行编译时是通过某一逻辑语法来实现的。如LL1、LR1等。使用不同的语法,对编译的结果便有所不同。在通用的c编辑器中,一般是向右查询一个运算符号。也就是说,在编译时,是比较两个相邻的运算符号的优先级,对高优先级的符号进行处理,并将结果压入堆栈,然后在判断少了该符号的式子的处理顺序。
如1+2*3*4+5。先判断1+2*3中的+和*。乘的优先级高,所以进行2*3的操作。第一次处理后的结果为1+st*4,其中的st是指被压入堆栈的2*3=6的结果。使用同样的规则,编译器发现*仍然高过+,则从堆栈中取出6,使用6和4向乘。并在次将结果压入堆栈st。于是运算式变成了1+st+5,其中st的值为24。继续处理。两个+优先级相同,先处理左边的。于是从堆栈中取出24执行1+24,并在度将结果压入堆栈。最后执行st+5得到结果。

将++的处理和普通二维运算符的处理结合起来,让我们一步步看看(++i)+(++i)+(++i)是如何处理的。
i=3;
当处理先进行(++i)+处理,发现++i等级高,于是处理++i。特殊的情况发生了,这时++i的是对i本身相加,其结果并没有被压入堆栈。堆栈中仍为空,但i值却被更改为4。计算机继续处理i+(++i)。++的等级还是比+高。于是再度处理++。i的值再次被加了一。成了i+i+。因为++取地址运算的特殊性,令到这里的两个i的值都为5。同时堆栈还是没有数据。继续处理i+i+,两个优先级相同的运算符。i+i被执行,结果为10,结果被压入堆栈st,成了st+(++i)。再执行是是执行++,i被加一成了6。于是为st+i。最后从堆栈中取出st==10和i==6相加。最后结果为16。

这就是为什么(++i)+(++i)+(++i)会等于16了。在不少书上都忽略了这种情况从而得出不是15就是18的结论。虽然不能说错误,但这种没经过详细分析的结果确会引导读者走相错误的学习方向。假如您学过编译原理的话,我建议使用编译原理的语法来分析一下,可不要说编译原理完全无用呀。
Yardwand 2002-04-21
  • 打赏
  • 举报
回复
看看潭浩强第二版《C程序设计》吧。

每个编译器处理方法不一样。换种更明确的写法吧!

自加自减有时会产生意想不到的结果,伤脑筋!!

linyjing 2002-04-21
  • 打赏
  • 举报
回复
我看完了。我只是一个初级的学习者,一些名词还不大明白,不过道理基本上明白了,这跟我们实践总结的经验是一致的。但是,问题在于,我之前大体思路也是如此,(当然不如你的清晰),这个规律并不适用于在TC中1)而当表达式为
(++i)+(i++)+(i--)*(--i)*(++i)时却先算乘法,为何不先算加法?
linyjing 2002-04-21
  • 打赏
  • 举报
回复
谢谢,真是太感谢了。我还没有看完,你能写这么多,我就已经很感谢了,至少不是所有人都是敷衍了。谢谢
ckacka 2002-04-21
  • 打赏
  • 举报
回复
加上更多的括号来明确你的思路。
jamesfangjing 2002-04-21
  • 打赏
  • 举报
回复
根据编译器不一样,结果也不一样。
作为一个题目看看可以,但是自己写的时候,最好不要这样写!
挺拔的劲松 2002-04-20
  • 打赏
  • 举报
回复
这种问题已不知问了多少遍了,潭浩强第二版《C程序设计》中有描述,在C的不同版本中,所得值也不同。因此书中指出在编程中尽量避免以上这种表达式出现。
lbl20020123 2002-04-20
  • 打赏
  • 举报
回复
愚蠢的写法。

无聊的问题。

节贴吧。
neptunez 2002-04-20
  • 打赏
  • 举报
回复
每个编译器处理方法不一样。所以请尽量不要这样写
zhuimengrencn 2002-04-20
  • 打赏
  • 举报
回复
老大!在C中应尽量避免这种情况!
owenszp 2002-04-20
  • 打赏
  • 举报
回复
C的版本不同,有的运算顺序也不同!
yang_yingfeng 2002-04-20
  • 打赏
  • 举报
回复
换一种更好的写法
linyjing 2002-04-20
  • 打赏
  • 举报
回复
问题是还是没有答案啊

69,382

社区成员

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

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