C/C++中const变量与指针所指内容的改变

先看一个很非常相当基础的C的代码哈~

void main()
{
      const int a=5;
      int * b=(int*)&a;
      *b=8;
      printf("%d",a);
}

大家先想想这个地方的输出到底应该是什么吧!

为了大家看的更清楚一些,我把程序稍稍修改一些,如下:

#include <cstdio>

int main()
{
 	const int a=5;
 	int * b=(int*)&a;
 	printf("%d\n",b);
 	printf("%d\n",*b);
 	*b=8;
 	printf("%d\n",a);
 	printf("%d\n",*b);
 	return 0;
}

结果输出:
1245024
5
5
8

说明*b=8确实有替a所在的地址赋值。
我在vs2008下编译输出汇编文件,摘选main函数部分汇编代码,加上我的理解注释,如下:

_b$ = -20      ; size = 4
_a$ = -8      ; size = 4
_main PROC      ; COMDAT

; 4    : {

 push ebp
 mov ebp, esp //esp为堆栈指针,ebp=esp
 sub esp, 216    ; 000000d8H
 push ebx
 push esi
 push edi
 lea edi, DWORD PTR [ebp-216]
 mov ecx, 54     ; 00000036H
 mov eax, -858993460    ; ccccccccH
 rep stosd

; 5    :  const int a=5;

 mov DWORD PTR _a$[ebp], 5 //变量a存放在堆栈区,赋值为5

; 6    :  int * b=(int*)&a;

 lea eax, DWORD PTR _a$[ebp]
 mov DWORD PTR _b$[ebp], eax  //b的值确实是变量a所在的地址

; 7    :  printf("%d\n",b);

 mov esi, esp
 mov eax, DWORD PTR _b$[ebp]
 push eax
 push OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 8    :  printf("%d\n",*b);

 mov esi, esp
 mov eax, DWORD PTR _b$[ebp]
 mov ecx, DWORD PTR [eax]
 push ecx
 push OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 9    :  *b=8;

 mov eax, DWORD PTR _b$[ebp]
 mov DWORD PTR [eax], 8 //确实改变了a变量地址的内容

; 10   :  printf("%d\n",a);

 mov esi, esp
 push 5  //这里就是问题所在,由于const关键字,编译器认为a与5是等价的,所以不再读取内存,而是直接用5代替a
 push OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 11   :  printf("%d\n",*b);

 mov esi, esp
 mov eax, DWORD PTR _b$[ebp]
 mov ecx, DWORD PTR [eax]
 push ecx
 push OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 12   :  return 0;

 xor eax, eax

; 13   : }

总结起来,就是const关键字令编译器认为a与常量5等价,所以输出的结果还是5。

可以试试输出下面一句,有惊喜。原因我不解释了,自己想想吧:)
printf("%d\n",*(((&a)+1)-1));

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值