const变量详解及与define宏定义的区别

在c语言中,用const修饰的变量的值默认不可修改,

const局部变量其在内存中分配的地址空间与普通局部变量一样,分配在栈区,(所以const局部变量可以使用指针修改该变量所在地址的值)。

const全局变量其在内存中分配的地址空间在文字常量区,该内存区域的只读属性保证了const全局变量不可被修改(所以const全局变量不可使用指针直接修改其所在地址的值,编译可以通过,但是运行时会报段错误)。


在c++中,用const修饰的变量的值默认不可修改,

在c++中编译器会对const变量进行优化,把它放到符号表中,不为其分配存储空间,在编译时进行类似于宏定义的操作,在出现const变量的地方在编译时就替换成其对应的值,所以这里是不会为它分配内存的,只有对const变量使用extern关键字或者取地址操作时才对其分配内存。

const局部变量使用extern关键字或者取地址操作后分配的地址空间与普通局部变量一样,分配在栈区,(所以const局部变量可以使用指针修改该变量所在地址的值,由于在编译时出现const变量的地方都已经替换成其对应的值了,所以即使改变了地址的值,在最后输出const变量的值依然是改变前的,只是const变量所在地址的值改变了)

例子:

#include <iostream>
using namespace std;
int main()
{
      const int a=1;
      int *p=(int*)&a;     //这里编译器为a在栈区分配了内存空间
      *p=2;
      cout<<"*p="<<*p<<endl<<"a="<<a<<endl; //这里其实在编译时已经使用1替换了a了,相当于cout<<"*p="<<*p<<endl<<"a="<<1<<endl,所以a输出的>        值不变,输出依然是1。
      return 0;
}

输出结果:

*p=2
a=1


这里可以使用volatile关键字告诉编译器a是随时可能发生变化的,每次使用它的时候必须从内存中取出a的值,因而编译器生成的汇编代码会重新从a的地址处读取数据用于输出。

代码可以改为如下样子,则a可以输出改变后的值:

<span style="font-size:12px;"><span style="color:#666666;">#include <iostream>
using namespace std;
int main()
{
     </span><span style="color:#ff0000;"> volatile const int a=1;</span><span style="color:#666666;">
      int *p=(int*)&a;     //这里编译器为a在栈区分配了内存空间
      *p=2;
      cout<<"*p="<<*p<<endl<<"a="<<a<<endl; //这里其实在编译时已经使用1替换了a了,相当于cout<<"*p="<<*p<<endl<<"a="<<1<<endl,所以a输出的>        值不变,输出依然是1。
      return 0;
}</span></span>

输出结果:

<span style="font-size:12px;">*p=2
a=2</span>


const全局变量使用extern关键字或者取地址操作后分配的地址空间在文字常量区,该内存区域的只读属性保证了const全局变量不可被修改(所以const全局变量不可使用指针直接修改其所在地址的值,编译可以通过,但是运行时会报段错误)。


const变量与define宏定义的区别 
(1) 编译器处理方式不同 
define宏是在预处理阶段展开。 

const变量在编译时确定其值。
(2) 类型和安全检查不同 
define宏没有类型,不做任何类型检查,仅仅是展开。 
const变量有具体的类型,在编译阶段会执行类型检查。
 (3) 存储方式不同 
define宏仅仅是展开,有多少地方使用,就展开多少次,宏本身不会分配内存,宏展开后的立即数是会占用内存的。(展开多少次就分配多少次内存)

编译器通常不为普通const变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,编译时对其进行类似于宏定义的操作,在出现const变量的地方就替换成其对应的值,没有了存储与读内存的操作,使得它的效率也很高。只有在对const变量使用extern关键字或者取地址操作时才会为它分配存储空间,且const变量从汇编的角度来看,操作const变量时只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const变量在程序运行过程中只有一份拷贝,不会多次分配存储空间。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值