读书人

关于自增运算符的有关问题

发布时间: 2012-03-04 11:13:34 作者: rapoo

关于自增运算符的问题
在 < <pointers on C> > 里说,这种:

int a=0;
++a=10; //应该是不能通过编译的,因为++a返回的是一个右值,对右值无法赋值


我做了一下试验,结果发现与书不一致:

++a=10; //能正常运算,当然结果是10
a++=10; //不能通过编译


而我原以为++a=10的确不应该通过,而a++应该通过才对.
另外根据C++里写重载++操作符的作法,应该是两种方法都能通过编译才是.
没想到实验结果是上面那样.

为什么会出现这种情况呢?

[解决办法]
如果把a++和++a想象成为函数的话,它们的实现是这样的:
// C++伪代码
int a++()
{
int n = a;
a += 1;
return n;
}

int& ++a()
{
a += 1;
return a;
}
a++返回的是一个临时变量,因此它不能成为一个左值(l-value)
++a返回的是a本身,可以作为左值出现在等号左边.
[解决办法]
a++=10; //不能通过编译
优先级问题
_________________________
这个似乎不是优先级的问题
编译的错误位: non-lvalue in assignment

假设可以通过,把10给了a,然后对10自加,这是不允许的(不知道这样理解算不算对)

对于++a=10;
反汇编出来是:

pushl%ebp
movl%esp, %ebp
subl$24, %esp
andl$-16, %esp
movl$0, %eax
movl%eax, -8(%ebp)
movl-8(%ebp), %eax
call__alloca
call___main
movl$0, -4(%ebp)
leal-4(%ebp), %eax
incl(%eax)-------a自加
movl$10, -4(%ebp)
movl-4(%ebp), %eax
movl%eax, 4(%esp)-----10给了a
movl$LC0, (%esp)
call_printf
movl$0, %eax
leave
ret
--------------
原程序是:
#include <stdio.h>
int main()
{
int a=0;
++a=10;
printf( "%d ",a);

}
---------
编译器把a自加后的值给了eax,然后又把10给了eax。
所以这个是可以的

[解决办法]
C与指针是讲指针的比较好的书籍。它在其它问题上的描述,你就别看了。这不是它的强项,出错也很正常。
而且,C与指针是很老的一本书了,在目前编译器下,已经有很多知识是过时的了。看的时候主要是掌握原则。细节必须自己多实践,并且自己去更新它。
[解决办法]
C++是这么规定的:a++=10; 如果a是内建数据类型比如int,不能通过编译;如果a是自定义数据类型,则可以编译通过。
因为在C++里,内建数据类型是2等公民,用户自定义数据类型是头等公民。
自定义数据类型的临时变量,可以被修改。
[解决办法]
C++是这么规定的:a++=10; 如果a是内建数据类型比如int,不能通过编译;如果a是自定义数据类型,则可以编译通过。
因为在C++里,内建数据类型是2等公民,用户自定义数据类型是头等公民。
自定义数据类型的临时变量,可以被修改。

===================================================================

也许a++的operator++(int)应该返回const T。这样就能和内建数据类型一样了。
我的感觉是,用户自定义数据类型要尽量和内建数据类型行为一致。

读书人网 >C++

热点推荐