• 从汇编来看i++与++i


    故事背景,一个正在c语言的家伙,问我++i 和 i++的问题,我当时由于要去上课没给他说,正好今晚有空就測试了一下例如以下代码:

    编译环境:VS2010  语言:C++

    复制代码
     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main(void)
     5 {
     6     int a = 1;
     7     int b = 1;
     8     int c;
     9 
    10     c = a++;
    11     c = ++b;
    12 
    13     return 0;
    14 }
    复制代码

    一、我们站在汇编的角度来说明一下问题:

    可能你没学过汇编,只是没关系,我们先来科普一下汇编基本知识。(我自己也不会汇编,仅仅是能看懂一些简单汇编代码)

    -----------------------------------------------------------------

    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.

    复制代码
     1 int a = 1;
     2 00EC136E  mov         dword ptr [a],1    //给a赋值1
     3     int b = 1;
     4 00EC1375  mov         dword ptr [b],1    //给b赋值1
     5     int c;
     6 
     7     c = a++;
     8 00EC137C  mov         eax,dword ptr [a]  //将a=1放入eax=1寄存器中
     9 00EC137F  mov         dword ptr [c],eax  //将eax=1放入c=1的地址中
    10 00EC1382  mov         ecx,dword ptr [a]  //将a=1放入ecx=1寄存器中
    11 00EC1385  add         ecx,1              //将ecx=1和1相加,并放入ecx=2寄存器中
    12 00EC1388  mov         dword ptr [a],ecx  //将ecx=2寄存器里的值放入a=2中
    13     c = ++b;
    14 00EC138B  mov         eax,dword ptr [b]  //将b=1放入eax=1寄存器中
    15 00EC138E  add         eax,1              //将eax=1与1相加,并放入eax=2寄存器中
    16 00EC1391  mov         dword ptr [b],eax  //将eax=2寄存器里的值放入b=2中
    17 00EC1394  mov         ecx,dword ptr [b]  //将b=2放入ecx=2寄存器中
    18 00EC1397  mov         dword ptr [c],ecx  //将ecx=2寄存器里的值放入c=2中
    19 
    20     return 0;
    21 00EC139A  xor         eax,eax  
    22 }
    复制代码

    从上面的一段汇编代码中我们能够非常清晰的看到,汇编后:

    1)c = a++;   当中c的值是1,可是a中的值却已经变化为2了。

    2)c = ++b;   当中c的值是2,b的值也是2。

    二、以下用C++中的 ++i 与 i++ 的重载演示样例来说明一下问题:

    复制代码
     1 /*win7_32bit,VS2010,2014年8月19日08:16:11*/
     2 #include <iostream>
     3 using namespace std;
     4 
     5 class Test
     6 {
     7 public:
     8     Test(int var) : m_var(var)
     9     {}
    10     //重载i++
    11     const Test operator++(int)//返回const的目的在于,使"i++ = 12"这样的写法非法(注意,这里不能返回栈上的引用)
    12     {
    13         Test t = *this;   //保存原来的数据
    14         ++m_var;
    15         return t;         //返回原来的数据
    16     }
    17     //重载++i
    18     Test& operator++()    //为了支持"++i = 10"这样的写法,我们返回一个对象的引用
    19     {
    20         ++m_var;
    21         return *this;
    22     }
    23     //重载输出流
    24     friend ostream& operator<<(ostream& os, const Test& t);
    25 private:
    26     int m_var;
    27 };
    28 ostream& operator<<(ostream& os,const Test& t)
    29 {
    30     os<<t.m_var;
    31     return os;
    32 }
    33 
    34 int main(void)
    35 {
    36     Test a(2);
    37     Test b(3);
    38     cout<<a++<<endl;//result:2
    39     cout<<++b<<endl;//result:4
    40     ++a = 10;       //ok
    41     cout<<a<<endl;  //result:10
    42     //b++ = 12;  const 不能赋值,error
    43 
    44     return 0;
    45 }
    复制代码

    --------------------------------------------------------------

    原文地址:http://www.cnblogs.com/nchar/p/3913724.html 

  • 相关阅读:
    JVM内存划分
    AIO
    软件精华收藏-[Windows] Photoshop 八零后的回忆版(只是40M)
    如何在 Ubuntu 中切换多个 PHP 版本
    wamp server 3.2.2.2 (64) 设置局域网访问
    WordPress站点遇到了致命错误解决方法,请查看您的站点的管理电子邮箱来获得指引
    WordPress主题开发:开启文章缩略图功能
    如何修改discuz首页logo
    Discuz怎么设置VIP用户组,dz用户vip组在哪添加
    discuz帖子中的图片和文字如何增加超链接呢?
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4073433.html
Copyright © 2020-2023  润新知