| 编程中国 | 业界新闻 | 技术文章 | 视频教程 | 下载频道 | 程序源码 | 个人空间 | 编程论坛
全能ASP/PHP/ASP.NET主机,支持月付专业 MSSQL 数据库空间,支持月付专业 MySQL 数据库空间,支持月付赛孚耐:软件保护加密专家
身份认证令牌USB KEY   
共有 471 人关注过本帖
标题:[讨论]反思大家之前讨论过的一个问题
收藏  订阅  推荐  打印 
百年不亮
Rank: 4
等级:高级会员
威望:8
帖子:781
积分:8160
注册:2006-4-14
[讨论]反思大家之前讨论过的一个问题

之前的一个帖子中提到关于自增前缀和后缀的问题,帖子在这里:http://bbs.bc-cn.net/dispbbs.asp?boardid=56&replyid=58792&id=124908&page=20&skin=0&star=1
int main()
{
int x=5;
int *p=&++x;
int *q=&x++; //error C2102: '&' requires l-value
return 0;
}

Cpp1.cpp
C:\Documents and Settings\Administrator\桌面\daima\Cpp1.cpp(6) : error C2102: '&' requires l-value


最后大家争论的焦点就在为什么&++x合法,而&x++会出错,有人提到我们在c++中重载前缀自增时直接将原始对象加一,最后返回原始对象的引用,所以&++x取的是原始对象的地址,是合法的。而在后缀的实现中是通过将原始对象的值赋给一个临时对象,再将原始对象加一,最后返回临时对象的值,&x++就是取一个临时对象的地址,所以是错误的操作。我看后觉得这是有道理的,但是这只是推测,不敢确定c/c++中内置类型也是这样实现的,近来翻看Bjarne Stroustrup 的 <<The C++ Programming Language>>,发现有一段话如下:

6.2.5 Increment and Decrement
The ++ operator is used to express incrementing directly,rather than expressing it indirectly using a combination of an addition and an assignment. By definition, ++lvaue means lvalue+=1, which again means lvalue=lvalue+1 provided lvalue has no side effects. The expression denoting the object to be incremented is evalued once(ovly). Decrementint is similarly expressed by the -- operator. The operators ++ and -- can be used as both prefix and postfix operators.The value of ++x is the new(that is, incremented)value of x. For example, y=++x is equivalent to y=(x+=1). The value of x++, however, is the old value of x. For example, y=x++ is equivalent to y=(t=x,x+=1,t), where t is a variable of the same type as x.

最后两句话就是我关心的:x++的值是x自增之前的旧值。例如y=x++相当于y=(t=x,x+=1,t),其中t是和x相同类型的变量

对比y=++x is equivalent to y=(x+=1) 和 y=x++ is equivalent to y=(t=x,x+=1,t),可以看出前缀和后缀的本质差别,&++x等价于&(x+=1)即(x+=1,&x); &x++等价于&(t=x,x+=1,t)即&t.

有了Bjarne Stroustrup他老人家的话自己终于放心了。
搜索更多相关主题的帖子: int  skin  
2007-5-19 19:57
kisscjy
Rank: 3Rank: 3
等级:中级会员
帖子:217
积分:2322
注册:2007-4-9

对比y=++x is equivalent to y=(x+=1)y=x++ is equivalent to y=(t=x,x+=1,t),可以看出前缀和后缀的本质差别,&++x等价于&(x+=1)即(x+=1,&x); &x++等价于&(t=x,x+=1,t)即&t.

呵呵,不看不知道,一看吓一跳~~~


每当我一晚写下70,80个程序时,你还真以为,这都是我一个人干的.....不过说真的,其实都是抄书的~~ ^@^
2007-5-19 21:02
aipb2007
Rank: 12Rank: 12Rank: 12
来自:CQU
等级:贵宾
威望:40
帖子:2881
积分:29414
注册:2007-3-18

受教了,

Fight  to win  or  die...
2007-5-20 17:07
神vLinux飘飘
Rank: 12Rank: 12Rank: 12
等级:贵宾
威望:87
帖子:6085
积分:61226
注册:2004-7-17

x++的确是个临时变量,因为是下一次才进行增加
而++x则在这次之前就已经修改好原地址的值了

所以&x++会出现:错误: 单目 ‘&’ 运算中的左值无效

泛出微微的蓝色的光,像有生命般涌动着,闪烁着,平滑而优美,达到了机械和美学结合的最高境界,向一件艺术品一样,默默的展示着,寂寞而孤傲,只有宇宙才能证实它的存在,只有永恒可以于它并存
2007-5-21 01:49
yuyunliuhen
Rank: 12Rank: 12Rank: 12
等级:贵宾
威望:20
帖子:1423
积分:14506
注册:2005-12-12


int main()
{
int x=5;
int *p=&++x;
int *q=&x++; //error C2102: '&' requires l-value
return 0;
}

Cpp1.cpp
C:\Documents and Settings\Administrator\桌面\daima\Cpp1.cpp(6) : error C2102: '&' requires l-value


最后大家争论的焦点就在为什么&++x合法,而&x++会出错,有人提到我们在c++中重载前缀自增时直接将原始对象加一,最后返回原始对象的引用,所以&++x取的是原始对象的地址,是合法的。而在后缀的实现中是通过将原始对象的值赋给一个临时对象,再将原始对象加一,最后返回临时对象的值,&x++就是取一个临时对象的地址,所以是错误的操作。我看后觉得这是有道理的,但是这只是推测,不敢确定c/c++中内置类型也是这样实现的,近来翻看Bjarne Stroustrup 的 <<The C++ Programming Language>>,发现有一段话如下:

“但是这只是推测”这个不只是推测吧,这个说服是对的

这里的情况和操作符重载的返回值是一样的;
比如说有这样的一个类:
class Interger{
private:
//.....
pubic:
friend const Interger operator ++(Interger &a); //prefix
friend const Interger operator ++(Interger &a, int); //postfix
//..some other member-funtion
};
在前缀(++a)和后缀(a++)的版本中,两个版本都改变了对象,这个对象不能作为常量类型,在对象改变后,前缀版本返回真值,我们希望返回改变后的对象,这样,前缀版本只需作为一个引用返回*this,而后缀版本返回改变前的值,必须创建一个代表这个值的对立的对象并且返回他,如果想保持原意,后缀版本必须以值的方式返回。
可以写这样的一个表达式,(++a).func(),那么func()的作用在a上,但如这样写的话(a++).func(),func()的作用在operator++的临时变量上,临时变量自动定为常量,这个操作会被编译器阻止。这个和LZ的例子是同一个道理。


Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-5-21 16:33
neverDie
Rank: 2
等级:注册会员
威望:1
帖子:123
积分:1330
注册:2007-5-5

&++a;
&a++ // a++返回的临时变量。

2007-5-21 18:12
百年不亮
Rank: 4
等级:高级会员
威望:8
帖子:781
积分:8160
注册:2006-4-14

回5楼的:
我不是说了吗,在自定义类型中,就是我们自己的类中,是这样的,这个是可以肯定的,但是,注意我说的是但是c/c++的内置类型是怎样的,我不知道,在没有一个权威确认的情况下,即使这样是解释的通,我们也只能说推测,不是吗?我在看了Bjarne Stroustrup的书之后才可以确认。
我认为讨论技术问题应该严谨,不能因为自己定义的类中重载++是那样实现的就说内置的类型如int类型也是这样。或许你会说我死板。


闭门读书中,有事发邮件到liunanst@gmail.com
2007-5-21 19:44
leilinghua
Rank: 1
等级:新手上路
帖子:26
积分:360
注册:2006-10-25

系统分配的临时变量释放了就不能再寻址了

潜心学习。。。。。 Q群:C&&C++ Lovers 39951868
2007-5-22 22:11
独孤风
Rank: 2
等级:注册会员
帖子:49
积分:590
注册:2006-11-7

受教了D


用心去感受程序的美妙,无忧无虑的探寻精彩.
2007-5-25 20:37
关于我们 | 广告合作 | 编程中国 | 清除Cookies | Archiver | WAP | TOP

编程中国 版权所有,并保留所有权利。鲁ICP备08000592号
Powered by Discuz, Processed in 0.091089 second(s), 9 queries.
Copyright©2004-2008, BCCN.NET, All Rights Reserved