const、static变量存放位置 解析

参考
博客01:https://blog.csdn.net/fayery/article/details/26505771

博客02:https://blog.csdn.net/qq_43152052/article/details/99306967

一、C语言中文网 http://c.biancheng.net/view/vip_2121.html

static 除了可以修饰全局变量,还可以修饰局部变量,被 static 修饰的变量统称为静态变量(Static Variable)。

不管是全局变量还是局部变量,只要被 static 修饰,都会存储在全局数据区(全局变量本来就存储在全局数据区,即使不加 static)。

全局数据区的数据在程序启动时就被初始化,一直到程序运行结束才会被操作系统回收内存;对于函数中的静态局部变量,即使函数调用结束,内存也不会销毁。

注意:全局数据区的变量只能被初始化(定义)一次,以后只能改变它的值,不能再被初始化,即使有这样的语句,也无效。

二、博客01

我们将以下面的例子介绍const变量和static变量的存放位置:

static int val_a = 1; // 初始化的静态变量

int val_b = 2; // 全局变量

const int val_c = 3; // const 全局变量

static int val_d; // 未初始化的静态变量

int val_e; // 未初始化的全局变量

int main()

{

static int val_f = 5;  // 初始化的局部静态变量

static int val_g;      //未初始化局部静态变量

int    val_h = 6;      //初始化局部变量

int    val_i;          //未初始化局部变量

const  int val_j = 7;  //const局部变量

return 0;

}

①static无论是全局变量还是局部变量都存储在全局/静态区域,在编译期就为其分配内存,在程序结束时释放,例如:val_a、val_d、val_h、val_i。

②const全局变量存储在只读数据段,编译期最初将其保存在符号表中,第一次使用时为其分配内存,在程序结束时释放,例如:val_c;
const局部变量存储在栈中,代码块结束时释放,例如:val_j。

参考:
链接:https://www.nowcoder.com/questionTerminal/d1622983cfdb47e98908f648f65576df?source=relative
来源:牛客网

rodata段(read-only-data)-常量区 rodata段存储常量数据,比如程序中定义为const的全局变量,#define定义的常量,以及诸如“Hello World”的字符串常量。只读数据,存储在ROM中。 注意:有些立即数与指令编译在一起,放在text段。 const修饰的全局变量在常量区;const修饰的局部变量只是为了防止修改,没有放入常量区。 编译器会去掉重复的字符串常量,程序的每个字符串常量只有一份。 有些系统中rodata段是多个进程共享的,目的是为了提高空间利用率。

③全局变量存储在全局/静态区域,在编译期为其分配内存,在程序结束时释放,例如:val_b、val_e。

④局部变量存储在栈中,代码块结束时释放,例如:val_h、val_i。

注:当全局变量和静态局部变量未赋初值时,系统自动置为0。

博客02

3、const变量的内存位于栈区或者静态存储区,不在符号表(常量表)中:

关于网上所说const修饰的变量存储在符号表中,这个并不完全是对的,const变量的内存位于C++的5大内存中的栈区或者静态存储区。在编译的时候,对于不试图通过内存来修改const变量值的,编译器统统将const变量存放在编译器内部产生的临时列表中,也就是所谓的符号表,该符号表与目标文件连接用的符号表是两个完全不同的东西。此临时符号表的作用就是提高效率,是编译器优化形成了,所以大家不必过多纠结const变量内存存放位置了,它的内存就是位于栈区或者静态存储区。
如果还有兴趣研究这个的,大家看看汇编代码不就完了,我本人菜鸡现在还不会。。还有关于这个的讨论,大家可以看看。。

测试代码如下:(该代码等学了汇编在做深入研究,现在先放一放。。)

const int i = 100;
int n = 0;
class CTest
{
public:
 CTest() :j(0), l(0) {};
 int l;
 const int j;
 static const int k = 102;
};

void test3()
{
 CTest ct;
 int m = 0;
 const int o = 0;
 
 long addri = (long)& i;
 long addrl = (long)& ct.l;
 long addrj = (long)& ct.j;
 long addrk = (long)& ct.k;
 long addrm = (long)& m;
 long addrn = (long)& n;
 long addro = (long)& o;

 cout << "addr i=" << addri << endl; //addr i = 2989028
 cout << "addr l=" << addrl << endl; //addr l = 15989288
 cout << "addr j=" << addrj << endl; //addr j = 15989292
 cout << "addr k=" << addrk << endl; //addr k = 2988856
 cout << "addr m=" << addrm << endl; //addr m = 15989276
 cout << "addr n=" << addrn << endl; //addr n = 29985882
 cout << "addr o=" << addro << endl; //addr o = 15989264
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值