全局变量、局部变量、静态全局变量、静态局部变量、堆变量、栈变量的异同

一、先介绍虚拟内存的分配:

虚拟内存(从0x00开始编码)
32位系统: 每个程序都独享4G内存(虚拟)
64位系统: 每个程序都独享16G内存(虚拟)

虚拟内存分为系统空间和用户空间

1、系统空间包括:(内核程序、驱动可以直接访问该区域)

1>内核

2>共享数据区(如剪切、粘贴,一般不能直接访问)

3>驱动程序(如显卡的显存对应的程序)一般程序只访问用户空间,只有驱动程序或者驱动程序导出的程序才能访问系统空间。

2、用户空间包括:

1>资源区(照片、音乐等等)

2>程序区(函数)

3>数据区:

动态存储区(栈区和堆区)

静态存储区又称全局区(全局变量和静态局部变量)

二、程序的内存分配

变量的存储都只涉及到用户空间,由C/C++编译的程序占用的内存分为以下几个部分:

1、栈区(stack)

由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap)

一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

3、全局区(静态区)(static)

全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放

4、文字常量区

常量字符串就是放在这里的。程序结束后由系统释放。

5、程序代码区

存放函数体的二进制代码。

三、变量的生命周期以及作用域

1、栈区变量:

计算机自动开辟回收内存区(自动变量)所有普通声明的变量均是栈区变量。

可见性:为距离最近的一对大括号

生命周期:为距离最近的一对大括号

2、堆区变量:

程序员手动申请的变量,需要手动释放(若不手动释放,可能引起内存泄漏直到重启才会再回收)[delete–new alloc–free]

可见性:为距离最近的一对大括号

生命周期:由程序员自己控制

3、全局变量:

【会自动赋初始值0或空】定义在所有函数之外,任意地方都可以使用。程序启动时开辟程序结束时自动回收

可见性:默认为本cpp,其它的加extern也可见(main.cpp、test.cpp是两个cpp文件)

[extern int test;

告诉编译器test变量不是在本cpp中定义,在link时,通过其它obj中获取。当前文件中只是引用]

生命周期:程序运行期一直存在

4、静态变量:

【不管是局部还是全局都会自动赋初始值0或空】static 当程序第一次执行到该变量开辟内存区,直到程序关闭自动回收。

可见性:为距离最近的一对大括号

生命周期:程序运行期一直存在

5、regist变量:

在CPU中的寄存器。运行性能高(但是不能保证一定在寄存器中)可当做栈区变量处理

四、说明静态全局变量,静态局部变量

静态局部变量:具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

静态全局变量:也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。静态全局变量限制了变量的作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。

把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。

static全局变量与普通的全局变量有什么区别:
static全局变量只初使化一次,防止在其他文件单元中被引用;

static局部变量和普通局部变量有什么区别:
static局部变量只被初始化一次,下一次依据上一次结果值;

static函数与普通函数有什么区别:
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

五、例子

void h();  
void f()  
{  
  int b=7;  
}  
int main()  
{  
  int a=5; //生命周期是整个main函数,  
  h();//调用h()函数时,a生命周期没有结束,如果将a传进h()函数内,h函数可以对a进行操作。但是a的可见性只在main函数内,如果没有传a进入h()函数,则h()函数内不可对a进行操作。  
  cout<<b;//错  
  return 0;  
}  
void h()  
{  
  cout<<a;//错  
}  

六、其他

通常情况下,全局变量写在.cpp文件中,不在.h文件中,预防重复编译
scanf()输入不能有空格
gets()输入可以有空格

————————————————
版权声明:本文为CSDN博主「麻子来了」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_22991367/article/details/72836180

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值