(C++反汇编系列)常量(第二课)_项目管理_非技术区_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 非技术区 > 项目管理 > (C++反汇编系列)常量(第二课)

(C++反汇编系列)常量(第二课)

 2015/1/30 15:17:11  逆天笨笨蛋  程序员俱乐部  我要评论(0)
  • 摘要:#define是个真常量,在编译时,代码中的宏名称将被替换掉。const常量是一个假常量,使用const定义的变量最终还是个变量,只是在编译器内进行检查,若发现被修改则报错。既然被const修饰的变量本质没有改变,那么就可以修改,这里不说它的实用性。(const的其他情况,比如修饰类中的数据成员,成员函数等,以后再讨论)intmain(){inti=1;constintb=2;constint*p1=&i;//不同通过指针p1修改i的值,但p1的值可以改变
  • 标签:汇编 c++

#define是个真常量,在编译时,代码中的宏名称将被替换掉。const常量是一个假常量,使用const定义的变量最终还是个变量,只是在编译器内进行检查, 若发现被修改则报错。既然被const修饰的变量本质没有改变,那么就可以修改,这里不说它的实用性。(const的其他情况,比如修饰类中的数据成员,成员函数等,以后再讨论)

int main()
{
    int i=1;
    const int b=2;
    const int *p1=&i;//不同通过指针p1修改i的值,但p1的值可以改变,即可以给p1重新赋值
    int const *p2=&i;//与p1完全一样
    int * const p3=&i;//p3不能指向const对象,不能给p3重新赋值,但可以通过p3修改i的值。
    const int * const p4=&i;//既不能通过*p4修改i的值,也不能对p4重新赋值。
    const int &p5=i;//引用必须初始化,不能重新赋值,同时此处不能通过p5修改i的值。

    int *p=(int *)&b;//不能将一个const对象赋给一个非const指针,
                    //但可以对const对象进行强制类型转换,去掉const修饰,从而修改const对象的数据
    *p=20;//修改const int b的值
    cout<<b<<endl;

    system("pause");
    return 0;
}

输出结果b的值依然是2,但并不说明b不能修改,只是编译器在编译期间发现b被const修饰,之后所有使用b的地方都被替换为其常量值。所以cout<<b<<endl在编译期间被优化为

cout<<5<<endl;

通过调试可以看到,通过指针p修改了const常量b的值。

    int i=1;
00F813BE  mov         dword ptr [i],1  
    const int b=2;
00F813C5  mov         dword ptr [b],2  
    const int *p1=&i;//不同通过指针p1修改i的值,但p1的值可以改变,即可以给p1重新赋值
00F813CC  lea         eax,[i]  
00F813CF  mov         dword ptr [p1],eax  
    int const *p2=&i;//与p1完全一样
00F813D2  lea         eax,[i]  
00F813D5  mov         dword ptr [p2],eax  
    int * const p3=&i;//p3不能指向const对象,不能给p3重新赋值,但可以通过p3修改i的值。
00F813D8  lea         eax,[i]  
00F813DB  mov         dword ptr [p3],eax  
    const int * const p4=&i;//既不能通过*p4修改i的值,也不能对p4重新赋值。
00F813DE  lea         eax,[i]  
00F813E1  mov         dword ptr [p4],eax  
    const int &p5=i;//引用必须初始化,不能重新赋值,同时此处不能通过p5修改i的值。
00F813E4  lea         eax,[i]  
00F813E7  mov         dword ptr [p5],eax  

    int *p=(int *)&b;//不能将一个const对象赋给一个非const指针,
00F813EA  lea         eax,[b]  
00F813ED  mov         dword ptr [p],eax  
                    //但可以对const对象进行强制类型转换,去掉const修饰,从而修改const对象的数据
    *p=20;//修改const int b的值
00F813F0  mov         eax,dword ptr [p]  //从指针p中取出b的地址放到eax中,然后将20存放到eax也就是b的地址中
00F813F3  mov         dword ptr [eax],14h  
    cout<<b<<endl;
00F813F9  mov         esi,esp  
00F813FB  mov         eax,dword ptr [__imp_std::endl (0F882A4h)]  
00F81400  push        eax  
00F81401  mov         edi,esp  
00F81403  push        2  //可以看到这里push的是2,而不是b地址中的数据,这就是对常量优化的结果(常量传播)

#define、const这两种类型在连接生成可执行文件后将不复存在。

 

发表评论
用户名: 匿名