故事背景,一个正在c语言的家伙,问我++i 和 i++的问题,我当时因为要去上课没给他说,正好今晚有空就测试了一下如下代码:
编译环境:VS2010 语言:C++
#include <iostream>
using namespace std; int main(void)
{
int a = ;
int b = ;
int c; c = a++;
c = ++b; return ;
}
一、我们站在汇编的角度来说明一下问题:
可能你没学过汇编,不过没关系,我们先来科普一下汇编基本知识。(我自己也不会汇编,只是能看懂一些简单汇编代码)
-----------------------------------------------------------------
1)dword ptr : dword -> double word 双字节 ptr -> pointer 指针
2)mov a b : 表示将b的值赋值给a
3)add x y : 表示取x的值和y的值相加,结果再放入x中
4)另外就是cpu的8个通用寄存器 :eax, ebx, ecx, edx, esi, edi, ebp, esp
eax :是"累加器", 它是很多加法乘法指令的缺省寄存器
ecx :是"计数器", 是重复(REP)前缀指令和LOOP指令的内定计数器
-----------------------------------------------------------------
好了,下面的汇编代码我再简单解释一下,就基本差不多了。
说明:以下汇编代码解释过程中,比如:eax=1,是表示目前eax中的值为1.
int a = ;
00EC136E mov dword ptr [a], //给a赋值1
int b = ;
00EC1375 mov dword ptr [b], //给b赋值1
int c; c = a++;
00EC137C mov eax,dword ptr [a] //将a=1放入eax=1寄存器中
00EC137F mov dword ptr [c],eax //将eax=1放入c=1的地址中
00EC1382 mov ecx,dword ptr [a] //将a=1放入ecx=1寄存器中
00EC1385 add ecx, //将ecx=1和1相加,并放入ecx=2寄存器中
00EC1388 mov dword ptr [a],ecx //将ecx=2寄存器里的值放入a=2中
c = ++b;
00EC138B mov eax,dword ptr [b] //将b=1放入eax=1寄存器中
00EC138E add eax, //将eax=1与1相加,并放入eax=2寄存器中
00EC1391 mov dword ptr [b],eax //将eax=2寄存器里的值放入b=2中
00EC1394 mov ecx,dword ptr [b] //将b=2放入ecx=2寄存器中
00EC1397 mov dword ptr [c],ecx //将ecx=2寄存器里的值放入c=2中 return ;
00EC139A xor eax,eax
}
从上面的一段汇编代码中我们可以很清晰的看到,汇编后:
1)c = a++; 其中c的值是1,但是a中的值却已经变化为2了。
2)c = ++b; 其中c的值是2,b的值也是2。
二、下面用C++中的 ++i 与 i++ 的重载示例来说明一下问题:
/*win7_32bit,VS2010,2014年8月19日08:16:11*/
#include <iostream>
using namespace std; class Test
{
public:
Test(int var) : m_var(var)
{}
//重载i++
const Test operator++(int)//返回const的目的在于,使"i++ = 12"这种写法非法(注意,这里不能返回栈上的引用)
{
Test t = *this; //保存原来的数据
++m_var;
return t; //返回原来的数据
}
//重载++i
Test& operator++() //为了支持"++i = 10"这种写法,我们返回一个对象的引用
{
++m_var;
return *this;
}
//重载输出流
friend ostream& operator<<(ostream& os, const Test& t);
private:
int m_var;
};
ostream& operator<<(ostream& os,const Test& t)
{
os<<t.m_var;
return os;
} int main(void)
{
Test a();
Test b();
cout<<a++<<endl;//result:2
cout<<++b<<endl;//result:4
++a = ; //ok
cout<<a<<endl; //result:10
//b++ = 12; const 不能赋值,error return ;
}
--------------------------------------------------------------