解析C++各种变量及区别
作者:三贝勒文子
在日常开发中,我们经常使用变量,常量,像下面的代码:
int ser_1; // 全局变量 const int ser_2; // 全局常量 static int ser_3; // 静态变量 void main(){ int serven_1; // 局部变量 const int serven_2; // 局部常量 static int serven_3; // 局部静态变量 func(serven_1); } void func(int para){ // 形参 int a; }
上面的一小段代码涵盖了变量、常量和静态变量,并且均定义了全局和局部。这些是我们经常使用到的定义变量的方式,但是你知道它们的区别吗?它们的作用域又是什么?它们的在内存中又是怎么样存放的?
一、分类
变量可以分为:全局变量、局部变量、静态全局变量、静态局部变量;
在C++的内存管理机制中,全局变量、静态全局变量和静态局部变量均存放在静态存储区域,局部变量存放在栈中,全局变量和静态变量如果在定义的时候没有初始化,那么编译器会将这些变量初始化为0。
二、作用域
作用域表示一个变量在使用过程中的范围,也就是在某个范围内,变量可以正常使用,出了这个范围,变量就失效了。
局部变量的作用域:局部变量的作用域在于函数体内部,出了函数的范围就是用不了了,像上述代码中的serven_1变量,只能在main函数中使用,出了main函数就使用不了。形参变量属于被调函数的局部变量,实参属于主调函数的局部变量。不同的函数可以使用一模一样的符号来定义变量,虽然符号一样,但是它们实际上是不相同的。像下面的代码,两个函数的符号serven_1都不一样,一个是int类型,一个是char类型。
void func_1(){ int serven_1 = 2; } void func_2(){ char serven_1 = 's'; }
全局变量的作用域:全局变量的作用域不属于某一个函数,它属于一个源程序文件,作用域是整个源程序,当需要在某个函数里面使用全局变量时,需要做声明,一般使用extern来做声明。当然啦,在同一个文件中就不需要做extern声明。全局变量和局部变量可以用相同的符号来定义,在定义局部变量的函数体中,如果使用了该符号则认为是局部变量,像下面的代码中,在函数func中使用serven_1时用的是局部变量。
int serven_1; // 全局变量,未初始化时则编译器默认其为0 void func(){ int serven_1 = 3; std::cout<<serven_1<<std::endl; // 这里打印的是3 }
三、存储区域
在C++的内存管理机制中,将整个存储区分为以下几块地方:代码区域(CODE)、常量区域(TEXT)、BSS区域、DATA区域、堆(HEAP)、栈(STACK)。
- 栈(STACK):由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作方式类似数据结构中的栈。
- 堆(HEAP):用于程序动态申请分配和释放空间。C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。注意:这里的“堆”并不是数据结构中的“堆”。
- 全局(静态)存储区:分为DATA段和BSS段。DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化区)存放未初始化的全局变量和静态变量。程序运行结束时自动释放。其中BBS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。
- 文字常量区(TEXT):存放常量字符串。程序结束后由系统释放。
- 程序代码区(CODE):存放程序的二进制代码。
在C/C++中,定义全局变量和局部变量时。全局变量(外部变量和静态变量),均是保存在全局存储区中,占用永久性的存储单元;局部变量(自动变量),保存在栈中,只有在所在函数被调用时才由系统动态在栈中分配临时性的存储单元。
变量存储区域分为动态存储区,静态存储区,寄存器存储区;其中寄存器存储也属于动态分配。
静态存储变量通常是在变量定义时就分配存储单元并一直保持不变, 直至整个程序结束;动态存储变量是在程序执行过程中,使用它时才分配存储单元, 使用完毕立即释放。
在C/C++语言中,对变量的存储类型说明有以下四种:
auto:自动变量
register:寄存器变量(存储在CPU寄存器中,寄存器运算速度远高于内存)
extern:外部变量
static:静态变量
自动变量和寄存器变量属于动态存储方式, 外部变量和静态变量属于静态存储方式。在介绍了变量的存储类型之后,可以知道对一个变量的说明不仅应说明其数据类型,还应说明其存储类型。因此变量说明的完整形式应为:
存储类型说明符 数据类型说明符 变量名,变量名…;
例如:
static int ser_1,ser_2; // 说明ser_1,ser_2为静态类型变量 auto char ser_3,ser_4; // 说明ser_3,ser_4为自动字符变量 static int ser_5[5]={1,1,1}; // 说明ser_5为静整型数组 extern int ser_6, ser_7; // 说明ser_6, ser_7为外部整型变量。
自动型变量存放在堆栈区中。堆栈区也是内存中一部分,该部分内存在程序运行中是重复使用的。堆区域一般是程序员我们自己来申请和释放的,像malloc申请内存;栈区域是编译器自动来管理的,像调用函数的形参变量和局部变量。
四、总结
1、全局变量的作用域是全局的(整个程序的),该变量只需要在其中的一个源程序文件定义,在其他的源文件中如果要使用到,就在变量的前面加上外部声明extern就可以使用了;
2、静态全局变量的生命周期是整个程序,只要程序没有停止,那么该变量都是占据着内存空间,但是它的作用域仅限于当前的源文件,这是它跟全局变量的区别就是全局变量在其他的源文件也是可以使用的;
3、静态局部变量的生命周期是整个程序,只要程序没有停止,那么该变量都是一直占据着内存空间,但是它的作用域仅限于定义它的函数体中;
4、局部变量的作用域是局部的,它也是auto自动变量,当函数执行完成,该变量就会被撤销,内存也被收回,存储在栈空间中;
5、为了降低模块间的耦合度,一般会尽可能地使用静态全局变量而不是全局变量;
6、为了降低模块间的耦合度,一般会尽可能地使用静态局部变量而不是静态全局变量;
到此这篇关于解析C++各种变量及区别的文章就介绍到这了,更多相关C++各种变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!