const 类型详解

const变量有全局的和局部的,C语言中全局的const变量默认为外连接,所以默认都是有内存地址的,C++中全局的const变量默认为内连接,它可以被编译 器放到符号表中作为编译期常量,所以在C中,constint k = 2; int a[k]是非法的,但在C++中是合法的。

这是全局const变量,局部的const变量在C和C++中一视同仁,都是放在函数局部栈中的,把编译后的可执行文件在汇编级调试一下马上就能看出来。

这样,问题就很明了在C和C++中,局部的const变量只是用来吓唬人的,想改它的值照样改,因为它存在于函数局部栈中,根本就不受任何权限的保护。当然修改的时候只要做个强制类型转化就好。

至于全局的const变量,C中默认是外连接,它有地址,有地址当然也能够被改掉,所以,你可以像在C语言中改变局部const变量那样通过指针来修改全 局const的值,编译时没有任何问题,连个warning都没有,只不过在运行时,你会得到一个segmentation fault而已。为什么呢?因为全局的const变量是存放在只读数据段里的,它比函数局部栈里的那些const变量高级,它受到只读数据段的权限保护, 所以,你试图修改一个只读数据段中的内容,会得到一个运行时错误。

const的变量在特定情况下可以通过指针修改,但是在另一些情况下是不能通过指针修改。

以下是在VC6下才测试。

1 不能修改的情况
[cpp]   view plain  copy
  1. #include <stdio.h>  
  2. int const a = 10;  
  3. void main(void)  
  4. {  
  5.  int *p = (int*)&a;  
  6.  *p = 20;  
  7.  printf("%d\n", *p);  
  8. }  

程序编译通过,但运行时错误:

指示a存储的空间不可以写,也就是没有写权限,不能修改其值。估计是存储在全局空间,且只有可读属性。

 
2 能修改的情况
[cpp]   view plain  copy
  1. #include <stdio.h>  
  2. void main(void)  
  3. {  
  4.  int const a = 10;  
  5.  int *p = (int*)&a;  
  6.  *p = 20;  
  7.  printf("&a=%d\n", &a);  
  8.  printf(" p=%d\n", p);  
  9.  printf(" a=%d\n", a);  
  10.  printf("*p=%d\n", *p);  
  11. }  

程序能正常运行,且常量被修改了,但是有一个问题:

为什么 printf("a=%d\n", a);

打印a=10?

难道一个地址空间可以存储不同的俩个值,当然不能,这是因为a是const变量,编译器对a在预处理的时候就进行了替换。编译器只对const变量的值读取一次。所以打印的是10。a实际存储的值发生了改变。但是为什么能改变呢,从其存储地址可以看出来,其存储在堆栈中。

验证如下:

[cpp]   view plain  copy
  1. #include <stdio.h>  
  2. void main(void)  
  3. {  
  4.  int const a = 10;  
  5.  int b = 20;  
  6.  int *p = (int*)&a;  
  7.  *p = 20;  
  8.  printf("&a=%x\n", &a);  
  9.  printf("&b=%x\n", &b);  
  10.  printf(" p=%x\n", p);  
  11.  printf(" a=%d\n", a);  
  12.  printf("*p=%d\n", *p);  
  13. }  

变量a和b的地址相近。

总结,const全局变量存储在全局存储空间,其值只有可读属性,不能修改;

const局部变量存储在堆栈中,可通过指针修改其值;

const变量在预处理是处理,编译器只对其值读取一次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值