故事背景,一个正在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 ;
}

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

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

汇编下的i++与++i的更多相关文章

  1. windows下实现微秒级的延时

    windowsintegeriostream汇编嵌入式任务 最近正在做一个嵌入式系统,是基于windows ce的,外接硬件的时序要微秒级的延时.1.微秒级的延时肯定不能基于消息(SetTimer函数 ...

  2. 伟福与Keil的比较--51汇编提高篇

    [写在前面] 本文适合有一定汇编水平的人(了解大半的汇编语句,能区分全角与半角符号,能够独立编写流水灯.数码管等程序),传授51单片机的汇编语言经验.如果您发现不少指令不知道意思,请从网上搜索入门教程 ...

  3. PC逆向之代码还原技术,第五讲汇编中乘法的代码还原

    目录 PC逆向之代码还原技术,第五讲汇编中乘法的代码还原 一丶简介乘法指令 1.乘法指令 2.代码还原注意问题 二丶乘法的汇编代码产生的格式 1.高级代码观看 2.乘法的汇编代码还原. 三丶乘法总结 ...

  4. [C/C++]linux下c-c++语法知识点归纳和总结

    1.c/c++申请动态内存 在c++中,申请动态内存是使用new和delete,这两个关键字实际上是运算符,并不是函数. 而在c中,申请动态内存则是使用malloc和free,这两个函数是c的标准库函 ...

  5. Java并发基础总结

    并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可 交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多 ...

  6. C/C++ 笔试题

    /////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程 ...

  7. C/C++ 笔试、面试题目大汇总

    1.求下面函数的返回值( 微软) int func(x) { int countx =0; while(x) { countx ++; x = x&(x-1); } return countx ...

  8. C/C++笔试题(很多)

    微软亚洲技术中心的面试题!!! .进程和线程的差别. 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2 ...

  9. (C++) 基本面试题(整理)

    1.new.delete.malloc.free关系 new/delete是C++的运算符.new 调用构造函数用于动态申请内存,delete调用对象的析构函数,用于释放内存. malloc与free ...

随机推荐

  1. Selenium webdriver 封装与重用

    WebDriver对页面的操作,需要找到一个WebElement,然后再对其进行操作,比较繁琐: WebElement element =driver.findElement(By.name(&quo ...

  2. 在DataTable和DataView中查找指定记录

    一.在DataTable中查找 1. 使用Select方法查找没有主键的表DataTable的Select方法返回一个DataRow数组,有四个重载的函数. DataRow[] drs = dt.Se ...

  3. java笔记12之面向对象初始

    1 概述 类:是一组相关的属性和行为的集合.是一个抽象的概念.     对象:是该类事物的具体表现形式.具体存在的个体. (1)面向对象思想     面向对象是基于面向过程的编程思想.         ...

  4. 二分图的最大匹配-hdu-3729-I'm Telling the Truth

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3729 题目意思: 有n个学生,老师询问每个学生的排名,每个学生都告诉了一个排名区间,求可能的最多的学 ...

  5. [Angular 2] Passing Observables into Components with Async Pipe

    The components inside of your container components can easily accept Observables. You simply define ...

  6. Win10系统修改MAC地址

    本地管理地址,输入想修改的MAC地址后,点确定即完成修改.在CMD窗口中,使用ipconfig 命令可以查看新的MAC地址. 再次钩选不存在,则还原为原来的MAC地址.

  7. NYOJ 116士兵杀敌(二) 树状数组

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116 士兵杀敌(一) 数组是固定的,所以可以用一个sum数组来保存每个元素的和就行,但是不 ...

  8. java08双重循环打印图形

    // 九九乘法表 外层循环每执行一次,内层循环执行一遍 for (int i = 1; i <= 9; i++) { // 外层控制的是行数 for (int j = 1; j <= i; ...

  9. WIN7 64位上 MYSQL的ODBC一些个人理解

    最近电脑中毒了,无奈之下把32位的xp换成了64位的win7,无聊耗时的搭完开发环境,装了vs6.0(忽略掉一切的不兼容),装完64位的mysql(“mysql-5.6.10-winx64.zip”) ...

  10. C# ashx生成的验证码

    public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg&qu ...