| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1809 人关注过本帖, 1 人收藏
标题:自加运算有新问题。
只看楼主 加入收藏
孤独_浪子
Rank: 2
等 级:论坛游民
帖 子:52
专家分:60
注 册:2010-1-13
收藏
得分:0 
回复9楼《C程序设计》上有详细的
比如int i=3;
(i++)+(i++)+(i++)
有的系统按照自左而右顺序求解括号的运算,求完第一个括号里的值后,实现i的自加,i=4,再求第二个,结果表达式相当于3+4+5=12。而另一些系统如TC ,MS C把3作为表达式中所有i的值,因此3个i相加的9,然后i自加3次,i的值变为6(来自《C程序设计》)
2010-02-04 18:11
jgzyd
Rank: 1
等 级:新手上路
帖 子:13
专家分:6
注 册:2010-1-19
收藏
得分:0 
呵呵,是4
2010-02-04 18:13
零下七度
Rank: 1
等 级:新手上路
帖 子:4
专家分:1
注 册:2010-2-3
收藏
得分:1 
对于5楼的算法,我有点体会,因为在C语言中数据值存放最新的数值。那么它就存放在他运算结前的那个数据。应该是这样的,不知道对不对,请高手指点下谢谢,
2010-02-04 20:54
BJ_BOY
Rank: 4
等 级:业余侠客
威 望:1
帖 子:77
专家分:225
注 册:2010-2-4
收藏
得分:1 
回复 楼主 skys
这需要了解序列点、表达式副作用的知识。我前几天买了本书:《C语言与程序设计大学教程》里有这个知识,这本书里讲得很清楚。我才知识自增自减原来涉及的知识还不少。
2010-02-04 20:56
零下七度
Rank: 1
等 级:新手上路
帖 子:4
专家分:1
注 册:2010-2-3
收藏
得分:0 
回复 14楼 BJ_BOY
那你给我们讲下啊 ,谢谢,我是个初学者
2010-02-04 20:59
BJ_BOY
Rank: 4
等 级:业余侠客
威 望:1
帖 子:77
专家分:225
注 册:2010-2-4
收藏
得分:0 
回复 11楼 孤独_浪子
这个解释基本正确,
例:(i++) + (i--) + (++i)中有三个副作用(见括号中),这三个副作用执行的顺序在C语言标准中未作规定,因此,不同的编译器会对该表达式将产生不同的结果。

《C语言与程序设计大学教程》一书中给出了非常好的解释,我觉得很合理,并在dev c++, vc++中证实了。建议大家找一本看看。
2010-02-04 21:00
BJ_BOY
Rank: 4
等 级:业余侠客
威 望:1
帖 子:77
专家分:225
注 册:2010-2-4
收藏
得分:0 
以下给是我从《C语言与程序设计大学教程》一书为大家摘抄出来的内容,这一内容显然能解答大家的问题,我认为可以终止大家对这一问题的讨论:)。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x = 3;                                 
int a;                                    
a = ++x + ++x + ++x;             /*等号右侧的表达式有三个副作用发生*/
printf("a = %d", a);                  
system("PAUSE");
return 0;
}

表达式++x + ++x + ++x有3个副作用:x自增1、x自增1、x自增1。问题的关键是:标准对于副作用的发生顺序未做定义。从而,对实现而言,可以先执行第一个++x,可能先执行第二个++x,也可能先执行第三个++x。标准只规定:一个表达式的全部副作用,不在到达该表达式紧邻的前一序列点前发生,并且一定在到达该表达式紧邻的下一个序列点之前发生完毕。

序列点被定义为程序执行过程中的这样一个点:该点前的表达式的所有副作用,在程序执行到达该点之前发生完毕;该点后的表达式的所有副作用,在程序执行到该点时尚未发生。C语言的大部分表达式都没有序列点,序列点会出现在:
   1) 完整表达式结束时。即出现在初始化语句、表达式语句、return语句中的表达式和条件表达式或switch语句中的控制表达式(包括for语句中的每个表达式)之后。
   2) &&、||、?:或逗号运算符的第一个操作数之后。
   3) 函数调用中求值参数和函数表达式之后。

a = ++x + ++x + ++x; 中,“;”后会被插入一个序列点(简单起见,称“;”就是序列点),因为程序执行到“;”前,表达式 a = ++x + ++x + ++x中的所有副作用都发生完毕,且“;”之后的表达式的所有副作用还未发生。因此,上述3个副作用只需要在遇到“;”之前结束就可。

在VS2005中,从上一个序列点(即int a;语句中的“;”)开始,表达式a = ++x + ++x + ++x的执行顺序为:

1)  执行三个副作用,使x变成6
2)  计算6 + 6,得12
3)  计算12 + 6,得18
4)  将18赋给a
5)  遇到序列点“;”

从而VS2005输出:a = 18。

在Dev C++中,从上一个序列点开始,表达式a = ++x + ++x + ++x的执行顺序为:

1)  先执行两个副作用,使x变成5
2)  计算5 + 5,得10
3)  再执行第三个副作用,使x变成6
4)  计算10 + 6,得16
5)  将16赋给a
6)  遇到序列点“;”

从而Dev C++输出:a = 16。

根据上面的描述,VS2005、Dev C++这两个实现都符合标准。因为,3个副作用都在两个紧邻的序列点间执行完毕。出现不同输出的主要原因就在于:3个副作用发生的顺序在两个不同实现中不一样。

由上可知,由于副作用的发生顺序是未定义的,这就意味着相应表达式的值是不确定的。因此,即使是掌握了副作用、序列点等相关知识,也不建议利用表达式求值的副作用。

实际工作中,完全可以通过引入中间变量,避开副作用造成了岐义。
2010-02-04 21:09
Devon_Ye
Rank: 4
来 自:广东
等 级:业余侠客
帖 子:124
专家分:282
注 册:2010-1-7
收藏
得分:0 
回复 9楼 hejirong
每个编译器编译出来的结果是有不同的
据我所知:TC和VC++6.0编译结果就不同
2010-02-04 22:22
wd_zhanghao
Rank: 1
等 级:新手上路
帖 子:3
专家分:1
注 册:2010-1-29
收藏
得分:1 
是4啊
2010-02-05 16:40
human84
Rank: 3Rank: 3
来 自:哈尔滨 / 重庆
等 级:论坛游侠
帖 子:154
专家分:141
注 册:2009-11-1
收藏
得分:1 
6楼答案4
2010-02-05 23:56
快速回复:自加运算有新问题。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017589 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved