详解C++中的自动存储

 更新时间:2020年09月27日 10:33:13   作者:chuyaoxin  
这篇文章主要介绍了详解C++中的自动存储,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下

C++有3种管理数据内存的方式即自动存储(栈存储)、静态存储和动态存储(堆存储)。在不同的方式下,内存的分配形式和存在时间的长短都不同。

下面对自动存储进行说明。

自动存储(栈存储)

对于函数的形参、内部声明的变量及结构变量等,编译器将在函数执行时为形参自动分配存储空间,在执行到变量和结构变量等的声明语句时为其自动分配存储空间,因此称其为自动变量(Automatic Variable),有的教科书也称其为局部变量,在函数执行完毕返回时,这些变量将被撤销,对应的内存空间将被释放。

事实上,自动变量的生存期只局限于它所在的代码块。所谓代码块,是包含在花括号对中的一段代码,函数只是代码块的一种,比较下面两段代码。

代码段1

int add(int m,int n)

{

  //z的生存期包括整个函数

  int z=m+n;

  return z;

}

代码段2

int add(int m,int n)

{

  if(m!=0)

  {

    //z的生存期包括在这个代码块中

    int z=m+n;

  }

  return z;//错误

}

在代码段1中,当函数返回时,变量z被撤销,对应内存空间被释放,但在代码段2中,在if代码块中声明的变量z,其生存期仅限于if结构的两个花括号之间,当程序执行到if结构的后花括号时,变量z已被撤销,其对应的内存空间被释放,此时,再执行“return z;”语句便会出错。

注意

理解代码块的含义十分重要,花括号不是判断代码块的唯一标准,把代码段2中if结构的花括号去掉,代码仍然是错误的,将“return z;”放在if结构中是正确的用法。

自动变量的生存期是局部的,这一特性使得程序员可以在不同的块内使用相同的变量名,用不着为使用不同的变量名绞尽脑汁。

1.什么是“栈”

栈(Stack)是一块存储区,而且是C++程序使用最频繁的存储区,其存储机理为“FILO”,即先进后出(First In,Last Out)。可以将其想象成一个装盘子的桶,最早放入的盘子在桶的底部,最晚放入的盘子在最顶部,取盘子时必须先从后放进去的盘子开始取,这就是所谓的先进后出原则。当一个代码块(包括函数,视为一种特殊的代码块)声明一个自动变量时,系统便为其在栈中开辟内存空间(常称“压入”push),该代码块结束后便将自动变量撤销,释放内存空间(常称“弹出”pop)。

注意

采用“栈”这种机制,C++程序能有效地节省所用内存空间。

2.auto关键字

auto是C++提供的存储类声明符,用于声明自动变量,除了auto声明符外,C++还提供了另外3个存储类声明符,分别是register(寄存器存储)、extern(外部存储)和static(静态存储)。在声明创建变量时,存储类声明符应放在数据类型声明符之前,如下所示。

存储类声明符 数据类型 变量名[=初始化表达式]

其中,初始化表达式是可选的,如下列代码声明创建了int型自动变量A,其只在函数demo()执行期间存在,demo()函数执行完毕后,变量A被撤销,对应内存被释放。

void demo()

{

  ……

  auto int A;

  ……

}

在前面给出的示例代码在声明自动变量时并没有加auto修饰符,实际上,auto常常可以默认,凡是在函数内部(不论是main()函数还是其他函数)的,没有用其他显式的存储类型声明符,编译器都认为是auto型自动变量。

3.register关键字

除了auto外,还可以通过存储类声明符register来声明自动变量,与auto唯一的不同在于:关键字register通知编译器,用户希望通过CPU寄存器,而不是“栈”来处理某个变量,从而可以在一定程度上加快该变量的访问速度。

提示

一般来说,CPU对寄存器的访问要快过对内存的访问。

用register声明的变量常称为寄存器变量,举例来说,下列代码声明了int型寄存器变量sum,并将其初始化为9,如下所示。

register int sum=9;

需要注意的是,即使用register声明了某个变量,编译器也不一定会满足它的要求。因为,CPU寄存器可能被占用或者无法存储指定类型的数据等,而且,现在的编译器一般可以自动决定应把哪些变量放在CPU寄存器中,因此,在C++程序中,register关键字很少使用。

使用register关键字会带来一定的负面效果,不管是否能满足要求,编译器认为register型自动变量是存储在CPU寄存器中的,而寄存器是没有内存地址的,所以,不能对register型自动变量进行取地址操作,下列代码是错误的。

void demo()

{

  ……

  register int sum=0;

  int*pSum=∑

  ……

}

注意

事实上,用auto和register声明的变量除了存储位置不同(一个是“栈”,而另一个可能是“栈”也可能是CPU寄存器)外,并无其他差异,我们可以将其统称为自动变量来考虑。

4.自动变量的初始化

可以在声明自动变量时对其进行初始化,也可以使用任何具有确定值的表达式为自动变量赋值,下列语句都是合法的(假定n为int型自动变量)。

n=2;

n=5*m;//m的值确定

n=add(4,6);

需要特别注意的是,如果没有在自动变量声明的同时对其初始化,其初始值是随机、不可预料的,为避免随机的初始值给程序带来麻烦,推荐在声明自动变量的同时对其显式初始化。

以上就是详解C++中的自动存储的详细内容,更多关于C++ 自动存储的资料请关注脚本之家其它相关文章!

相关文章

  • C语言标准库<math.h>和<setjmp.h>的实现

    C语言标准库<math.h>和<setjmp.h>的实现

    本文主要介绍了C语言标准库<math.h>和<setjmp.h>的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-11-11
  • C++详解使用floor&ceil&round实现保留小数点后两位

    C++详解使用floor&ceil&round实现保留小数点后两位

    这篇文章主要介绍了C++使用floor&ceil&round实现保留小数点后两位的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • C++代码实现网络Ping功能

    C++代码实现网络Ping功能

    这篇文章主要介绍了C++代码实现网络Ping功能,Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机,本文给大家介绍的非常详细,需要的朋友参考下吧
    2021-08-08
  • 虚函数表-C++多态的实现原理解析

    虚函数表-C++多态的实现原理解析

    这篇文章主要介绍了虚函数表-C++多态的实现原理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • 解读C++编程中派生类的构成和创建

    解读C++编程中派生类的构成和创建

    这篇文章主要介绍了解读C++编程中派生类的构成和创建,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++ STL之string的模拟实现实例代码

    C++ STL之string的模拟实现实例代码

    C++中有命名空间的存在,我们只需把我们的代码封到自定义的命名空间即可,下面这篇文章主要给大家介绍了关于C++ STL之string的模拟实现的相关资料,需要的朋友可以参考下
    2023-01-01
  • 掌握C++:揭秘写时拷贝与浅深拷贝之间的关系

    掌握C++:揭秘写时拷贝与浅深拷贝之间的关系

    探索C++的奥秘,本指南将揭秘写时拷贝与浅深拷贝之间的微妙关系,摸索这些复杂概念背后的逻辑,让你的编程技能瞬间提升,来吧,让我们一起进入这个引人入胜的C++世界!
    2024-01-01
  • 一篇文章带你了解C++的KMP算法

    一篇文章带你了解C++的KMP算法

    这篇文章主要介绍了c++ 实现KMP算法的示例,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下,希望能给你带来帮助
    2021-08-08
  • C/C++读写文本文件、二进制文件的方法

    C/C++读写文本文件、二进制文件的方法

    今天小编就为大家分享一篇C/C++读写文本文件、二进制文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 使用VS Code的开发环境配置教程图文详解

    使用VS Code的开发环境配置教程图文详解

    这篇文章主要介绍了使用VS Code的开发环境配置教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05

最新评论