注册 登录
编程论坛 C++教室

被a++和++a搞晕乎乎的童鞋们可以进来下啊~哈哈,顶顶~

xinyukkkk028 发布于 2011-05-11 00:28, 1061 次点击
之前很多朋友都问了我这个问题,处于方便,我就一次这个帖子解答了吧。。。其实很简单,因为每一个表达式都有一个返回值。
比如c++或者++c。这些都是一个表达式,而自增(或者自减)运算符的位置的不同,表达式的返回类型就不同。
前置的运算符返回的是对该对象的一个引用。就是说,返回的是一个地址,所以可以做连续运算,比如++++c这样的表达式是合法的。
但是后置运算法不一样。他返回的只是一个临时副本,就是说,返回的只是一个值而并没有一个修改权限(可以把它理解成为一个constant的值)
所以说c++++这样的表达式是不合法的,一般用的gcc或者vc编译器都会报错的吧。而且准确的说,后置运算符++是一个二元运算符。第一个参数是你做操作的对象本身,第二个参数实际上是编译器自动传入的一个int,而且这个值一般为0。就是说c++这个表达式的完整形式应该是 operator ++(int c,int),第二个参数实际上没有什么用处,只是为了和前置运算符区分以便重载而已。
总之,明白了前置返回的是引用而后置返回的是值的话,其实很好理解了。
这就是为什么a=(++c)+(++c);c=0;最后的a=4而不是3或者2或者别的什么答案了。你们明白咯吗
14 回复
#2
xinyukkkk0282011-05-11 00:32
木有人顶啊,木有人回帖啊。。。感觉白打字了啊
#3
donggegege2011-05-11 12:54
a++与++a的区别在于,a++是先进行赋值,然后进行加1.而++a则事先进行加1运算,然后进行赋值操作。
#4
rjsp2011-05-11 12:55
T& operator++ ()
{
    t += 1;
    return t;
}

const T& operator++( int )
{
    T temp = t;
    t += 1;
    return temp;
}
#5
Demon_JIE2011-05-11 20:25
在循环当中有时候 都没怎么区分这个
for(i = 1; i <= n; i++ or ++i)
都一样
#6
pangding2011-05-12 11:37
感觉楼主说的好多都不对呀……

比如 c++++ 这种,按传统的观念解释应该是左右值的问题。不是什么二元运算符的事。
后置++ 的重载应该算是一类特殊的语法,具体编译器如何实现,应该是没做规定。不是说一定要传个 int 参数过去。

还有你真的试过:
a=(++c)+(++c)
在 c=0 的时候值是 4 吗。
我觉得不一定。不过我没试。


不过看了楼主的这个帖子,确实帮我回忆了不少东西。
另外我还感觉到,c++ 里好多东西靠经验理解来的不一定对,虽然实际用上不会出什么问题,但还是小心应付好一点。
#7
xinyukkkk0282011-05-12 14:58
回复 6楼 pangding
回复6楼,a=(++c)+(++c)这个题我是自己试验过的,不管用GCC还是VC都是4.谢谢提出批评意见,对于左值右值我前部分已经有说明咯,也许是您忽略了,前置返回引用,引用当然是左值,后置返回值,当然是右值,只是说法不一样而已,嘿嘿,以后希望大家也能互相切磋切磋。我只是一个大一的学生。。这些只是我自己的经验。。只是有些学弟在问所以我就一次性把我的观点打了出来,至于您提到的那个后置传入默认参数的问题,这个不是我的说法。请参照机械工业出版社出版的《More Effective C++》由 Scott Meyers著,刘晓伟译的。第二章运算符里面有提到这个说法。。
#8
xinyukkkk0282011-05-12 15:00
以下是引用rjsp在2011-5-11 12:55:40的发言:

T& operator++ ()
{
    t += 1;
    return t;
}

const T& operator++( int )
{
    T temp = t;
    t += 1;
    return temp;
}


补充一点,这2个式子是正确的,这个就是解释了为什么C++返回的是自增前的值而如果用++c的取值是增加后的值了,希望能够使不是很明白的同学豁然开朗。
#9
xinyukkkk0282011-05-12 15:01
再祝今年马上高考的学弟学妹们高考成功!!!1热爱C++的人啊!高考伤不起啊!
#10
pangding2011-05-20 11:02
你试试这个代码,反正在我这(gcc 4.5)结果是 3。
程序代码:
#include <iostream>
using namespace std;

class Int {
public:
    int n;

    Int(int a = 0) : n(a) {}
    Int(const Int &a) : n(a.n) {}

    Int &operator++() { ++n; return *this; }
    Int operator++(int) { Int t(n); ++n; return t; }

    Int operator+(Int a) const { return Int(n + a.n); }
};

ostream &operator<< (ostream &os, const Int &a)
{
    os << a.n;
    return os;
}

int main(int argc, char *argv[])
{
    Int a, c;

    a = (++c) + (++c);

    cout << a << endl;

    return 0;
}

#11
xinyukkkk0282011-05-30 11:55
回复 10楼 pangding
请问您为什么要自己写一个int类呢?我说的就是GCC原本的int啊。。。。
#12
pangding2011-05-30 19:10
我只是想说你的分析并不是很对。

那个表达式的值是未定义的,这是个很常见的错误。不过好多人都喜欢问。
我觉得你比较爱学,所以启发一下。自己定义一个类,和内置类型的值都不一样,你还敢说原来的分析成立吗?

写过一段 c++ 程序的人非常害怕脱离类型谈问题。但他们同样也害怕带着类型一起谈。
C++ 的行为,经常不能从代码上理解。除非写代码的人有深厚的功力,否则代码也许做的从来就不是它看上去它应该做的事情。
#13
xinyukkkk0282011-06-12 19:48
回复 12楼 pangding
饿。。这倒是没有想到过。谢谢老师的启发。以后我想问题一定会更全面的~(ˇˍˇ) 想~
#14
obeey2011-06-13 12:41
Int operator+(Int &a) const

你做如上修改就是4了。因为你传入的是c的一份copy,而不是c本身。此copy的n刚刚加1,不为2,所以你的结果就为3了。
#15
xinyukkkk0282011-06-14 01:12
回复 14楼 obeey
顶楼上,对的,传入引用的话就不可能出现奇数了。
1