解析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++各种变量内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++中的局部变量、全局变量、局部静态变量、全局静态变量的区别

    局部变量(Local variables)与 全局变量: 在子程序或代码块中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序或代码块. 当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用:在其它地方全局变量起作用. 全局变量在程序开始运行期间就已经在内存中开辟了内存空间,直到程序结束才会释放这块内存空间. 全局变量要在其他文件中使用,需显示的声明这个变量,使用extern关键字声明(extern int

  • 一篇文章带你了解C++ static的作用,全局变量和局部变量的区别

    目录 1.static的作用 2.staic全局变量和局部变量的区别,存储位置? 区别: 我们自底向上的方式进行讲解: 总结 1.static的作用 (1) 修饰局部变量时,只初始化一次,延长了局部变量生命周期,直到程序结束才释放. (2)修饰全局变量,全局变量智能在本文件访问,不能在其他文件访问. (3)修饰函数同修饰全局变量类似,只能在本文件调用,不能在其他文件调用. (4)不想被释放的时候,可用static修饰. (5)考虑数据安全性,如当程序需使用全局变量时,应优先考虑static. 2

  • c语言和c++语言中const修饰的变量区别浅析

    目录 c: 修饰全局变量: 修饰局部变量: c++: 修饰全局变量: 修饰局部变量: 总结: 在c语言中: 在c++语言中: 总结 c: 修饰全局变量: 用const修饰的全局变量是没有办法直接修改的,间接的修改也是不成功的(语法可以通过,但是编译运行的时候会报错.)(const只要是修饰全局变量,那么就会储存到常量区中,收到常量区的保护.) 修饰局部变量: 但是如果用const修饰局部变量,同样的也是没有办法直接修改的,但是是可以间接修改的. int main() { const int b

  • 解析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 p

  • web面试之JS预解析与变量提升区别

    目录 什么是预解析? 变量和函数预解析的区别 重复声明var变量 变量提升和函数提升优先级 函数优先级大于变量优先级的深入探究 预解析流程 搜寻预解析关键字 执行预解析 几个需要注意的细节 什么是预解析? 概念: JS代码在在代码从上往下执行前,浏览器会先把所有变量声明解析一遍, 这个阶段叫预解析. 详讲 寻找作用域中的var 和function声明(匿名函数没有function声明,所以不会提升),然后对其进行事先声明, 并把赋值操作留在原地,再从上到下执行代码.这就是一个预解析的过程. 变量

  • vue数据监听解析Object.defineProperty与Proxy区别

    目录 前言 Object.defineProperty 与 Proxy 的区别 在使用上的差异 总结与思考 前言 总能深深感觉到自己能力有限,写这篇文章的目的纯粹是因为发现在实际工作中,和一些小伙伴交流时发现,虽然有些小伙伴大概知道 vue2 与 vue3 的区别,但并没有去进一步思考一些深一点的东西.尽管能力有限,但想着自己在起步时候的艰难,就想着分享一下自己的一些看法,虽然不一定有多深入,但能引起大家的一些思考也是好的. Object.defineProperty 与 Proxy 的区别 其

  • php中static 静态变量和普通变量的区别

    php中static 静态变量和普通变量的区别 在变量的前面加上static 就构成了静态变量(static 变量). static变量和普通变量的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的. 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它.由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误. static变

  • 浅谈MySQL存储过程中declare和set定义变量的区别

    在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅在类中生效.即只在存储过程中的begin和end之间生效. 2.@set定义的变量,叫做会话变量,也叫用户定义变量,在整个会话中都起作用(比如某个应用的一个连接过程中),即这个变量可以在被调用的存储过程或者代码之间共享数据.如何理解呢?可以看下面这个简单例子,很好理解. (1)先执行下面脚本,创建一

  • PHP 闭包获取外部变量和global关键字声明变量的区别讲解

    最近在学习workerman的时候比较频繁的接触到回调函数,使用中经常会因为worker的使用方式不同,会用这两种不同的方式去调用外部的worker变量,这里就整理一下PHP闭包获取外部变量和global关键字声明变量的区别. 闭包 闭包是一个常见的概念,我们通常可以将其与回调函数配合使用,可以使代码更加简洁易读. 闭包可以 通过拷贝的方式 让函数使用父作用域中的变量.如: $global = 'hello'; $bbb = function()use($global){ echo $globa

  • js中let和var定义变量的区别

    javascript 严格模式 第一次接触let关键字,有一个要非常非常要注意的概念就是"javascript 严格模式",比如下述的代码运行就会报错: let hello = 'hello world.'; console.log(hello); 错误信息如下: let hello = 'hello world.'; ^^^ SyntaxError: Block-scoped declarations (let, const, function, class) not yet sup

  • 简单了解java局部变量与成员变量的区别

    这篇文章主要介绍了简单了解java局部变量与成员变量的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 package java04; /* 局部变量和成员变量的不同: 1.定义的位置不一样 局部变量:定义在方法内部 成员变量:在方法外部,直接写在类中 2.作用范围不一样 局部变量:只有方法中能使用,除了方法就不能用 成员变量:整个类都可以用 3.默认值不一样 局部变量:无默认值,先赋值在使用 成员变量:如果没有赋值有默认值 4.内存的位置不

  • Python中类变量和实例变量的区别

    目录 一.前言 二.解决过程 三.总结 一.前言 有人提问了一个关于Python类变量和实例变量的问题,这里拿出来给大家分享下,一起学习. 是用英文提问的,当然了英文看上去也不难,有点二级英文基础,也看得懂,实在不行,在线翻译一下也问题不大了. 二.解决过程 这里主要涉及到三个部分,类属性,实例属性,及实例属性的引用对象指向性问题.在该例中counter为类属性,__first为实例属性,print函数中的counter为实例属性的引用对象指向性问题.当ExampleClass类实例化时,__i

  • java中静态变量和实例变量的区别详细介绍

    运行效果: 控制台效果: ================================================== 代码部分 ================================================== /hello_test/src/com/b510/test/StaticTest.java 复制代码 代码如下: /**  *   */ package com.b510.test; /**  * 在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例

随机推荐