const修饰符的作用

来源:互联网 发布:051级驱逐舰知乎 编辑:程序博客网 时间:2024/04/30 12:54

[cpp] view plaincopy
  1. /* 
  2. C/C++中规定,在变量前加const修饰符是将变量定义为常量,其值是不能修改的 
  3.  
  4. 但这个不能修改也只是针对编译器而言 
  5. */  
  6. #include <stdio h="">  
  7.   
  8. int main()  
  9. {  
  10.     const int a = 2;  
  11.     int *b,i = 0;  
  12.     printf("%d\n",a);  
  13.     b = (int*)&a;//强制转换一下,让编译通过  
  14.     *b = 10;  
  15.     __asm  
  16.     {  
  17.         push eax  
  18.         mov eax,a//把变量a的值给寄存器EAX(上边已经用*b=10改变了a的值了)  
  19.         mov i,eax//再把寄存器EAX的值给i  
  20.         pop eax  
  21.     }  
  22.     printf("a:%d\n",a);//有使用a的地方全被改成push 2了,而并没有去a的内存空间取值  
  23.     printf("*b:%d\n",*b);  
  24.     printf("i:%d\n",i);//其实a的内存空间的数值是被改变掉的  
  25.     //只是编译做了手脚,将有a出现的地方全改成a刚开始的值了  
  26.     return 0;  
  27. }//VC6.0编译通过  

[cpp] view plaincopy
  1. /*以下是VC6.0调试的汇编代码*/  
  2.   
  3. 1:    /* 
  4. 2:    C/C++中规定,在变量前加const修饰符是将变量定义为常量,其值是不能修改的 
  5. 3: 
  6. 4:    但这个不能修改也只是针对编译器而言 
  7. 5:    */  
  8. 6:    #include <stdio.h>  
  9. 7:  
  10. 8:    int main()  
  11. 9:    {  
  12. 0040D720 55                   push        ebp  
  13. 0040D721 8B EC                mov         ebp,esp  
  14. 0040D723 83 EC 4C             sub         esp,4Ch  
  15. 0040D726 53                   push        ebx  
  16. 0040D727 56                   push        esi  
  17. 0040D728 57                   push        edi  
  18. 0040D729 8D 7D B4             lea         edi,[ebp-4Ch]  
  19. 0040D72C B9 13 00 00 00       mov         ecx,13h  
  20. 0040D731 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
  21. 0040D736 F3 AB                rep stos    dword ptr [edi]  
  22. 10:       const int a = 2;  
  23. 0040D738 C7 45 FC 02 00 00 00 mov         dword ptr [ebp-4],2  
  24. 11:       int *b,i = 0;  
  25. 0040D73F C7 45 F4 00 00 00 00 mov         dword ptr [ebp-0Ch],0  
  26. 12:       printf("%d\n",a);  
  27. 0040D746 6A 02                push        2     /*是直接将2压入堆栈,并不是去取a的值*/  
  28. 0040D748 68 1C 20 42 00       push        offset string "%d/n" (0042201c)  
  29. 0040D74D E8 3E 39 FF FF       call        printf (00401090)  
  30. 0040D752 83 C4 08             add         esp,8  
  31. 13:       b = (int*)&a;//强制转换一下,让编译通过  
  32. 0040D755 8D 45 FC             lea         eax,[ebp-4]  
  33. 0040D758 89 45 F8             mov         dword ptr [ebp-8],eax  
  34. 14:       *b = 10;  
  35. 0040D75B 8B 4D F8             mov         ecx,dword ptr [ebp-8]  
  36. 0040D75E C7 01 0A 00 00 00    mov         dword ptr [ecx],0Ah  
  37. 15:       __asm  
  38. 16:       {  
  39. 17:           push eax  
  40. 0040D764 50                   push        eax  
  41. 18:           mov eax,a  
  42. 0040D765 8B 45 FC             mov         eax,dword ptr [ebp-4]  
  43. 19:           mov i,eax  
  44. 0040D768 89 45 F4             mov         dword ptr [ebp-0Ch],eax  
  45. 20:           pop eax  
  46. 0040D76B 58                   pop         eax  
  47. 21:       }  
  48. 22:       printf("a:%d\n",a);//有使用a的地方全被改成push 2了,而并没有去a的内存空间取值  
  49. 0040D76C 6A 02                push        2 /*第二次使用到a,还是直接将定义时的值给压入堆栈*/  
  50. 0040D76E 68 B4 2F 42 00       push        offset string "a:%d/n" (00422fb4)  
  51. 0040D773 E8 18 39 FF FF       call        printf (00401090)  
  52. 0040D778 83 C4 08             add         esp,8  
  53. 23:       printf("*b:%d\n",*b);  
  54. 0040D77B 8B 55 F8             mov         edx,dword ptr [ebp-8]  
  55. 0040D77E 8B 02                mov         eax,dword ptr [edx]       /*取a的内存空间的值*/  
  56. 0040D780 50                   push        eax               /*再压入堆栈*/  
  57. 0040D781 68 AC 2F 42 00       push        offset string "*b:%d\n" (00422fac)   
  58. 0040D786 E8 05 39 FF FF       call        printf (00401090)  
  59. 0040D78B 83 C4 08             add         esp,8  
  60. 24:       printf("i:%d\n",i);//其实a的内存空间的数值是被改变掉的  
  61. 0040D78E 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
  62. 0040D791 51                   push        ecx  
  63. 0040D792 68 A4 2F 42 00       push        offset string "i:%d/n" (00422fa4)  
  64. 0040D797 E8 F4 38 FF FF       call        printf (00401090)  
  65. 0040D79C 83 C4 08             add         esp,8  
  66. 25:       //只是编译做了手脚,将有a出现的地方全改成a刚开始的值了  
  67. 26:       return 0;  
  68. 0040D79F 33 C0                xor         eax,eax  
  69. 27:   }//VC6.0编译通过  
  70. 0040D7A1 5F                   pop         edi  
  71. 0040D7A2 5E                   pop         esi  
  72. 0040D7A3 5B                   pop         ebx  
  73. 0040D7A4 83 C4 4C             add         esp,4Ch  
  74. 0040D7A7 3B EC                cmp         ebp,esp  
  75. 0040D7A9 E8 62 39 FF FF       call        __chkesp (00401110)  
  76. 0040D7AE 8B E5                mov         esp,ebp  
  77. 0040D7B0 5D                   pop         ebp  
  78. 0040D7B1 C3                   ret  
  79.   
  80. /* 
  81. 总结,const修饰的变量是由编译在编译连接阶段进行检测的,检测到有代码段修改了其值就会提示语法错误 
  82. 而且每次使用该变量的值时,不是去内存空间去取,而是由编译直接将其值拿来参于编译连接 
  83. */  

 

 转自:http://blog.csdn.net/duke56/article/details/5825065

原创粉丝点击