变量/对象,你真的理解了吗?

变量/对象是程序的基本操作单位,所以深刻地理解变量是一件非常重要的事情(因为变量为大家一般所熟知,故下文皆以变量来描述)。

很多人可能会觉得,变量不是很简单吗,就是定义和使用。然而在慢慢深入一些领域,如大型程序构建,c++等面向对象语言等的学习。不难发现,会有大部分语法来阐述对象的建立和其内存的释放,如果没有很深理解对象,那么我们将会陷入繁杂的语法困境。

变量

基本定义

首先变量应该具有以下功能和性质

  • 类型,让编译器知道应该以什么方式处理变量。
  • 内容,变量存储内容。
  • 标识,让编译器知道当前是哪个变量,去哪里访问该变量。对编译器来说是内存地址,对程序员来说,就是绑定了内存地址的名字,也就是常说的变量名。
  • 生命周期,当程序执行离开变量所在的作用域

初始化/定义

很多人把初始化认为就是赋值,一个变量怎么才算被初始化呢?
一个变量被系统分配了内存,并且赋予初值才算被初始化。

访问一个变量/使用一个函数需要具备哪些条件?

1 告诉编译器你要使用哪个域或者是命名空间的变量,即你接下来使用的变量要在名字的有效使用区域
2 要保证变量已经被构造,并且在生命周期内。
3 具备访问变量的权限,例如类的成员函数,只有该类实例化的对象才能使用。

作用域和名字

作用域:

c++一般以花括号的起始和结尾为一个作用域。(为什么说“一般”,对于全局变量比较特殊)

名字

名字的有效使用区域:从变量声明到所在作用域的结尾。
因此,在使用名字前,一定要声明你所使用的是哪个具体的变量,如果已经在名字的有效使用区域,则不用再声明。

从最底层来了解变量和函数的访问

程序基本运行流程

首先,你应该知道,一个程序运行的基本流程:

  1. 系统加载程序代码到系统内存。此时程序的内存映像空间如下:

    关于内存映像,我就不一一介绍,主要我们需要理解的是,我们的代码段和全局变量都会被加载到内存。因为他们都是在整个程序执行过程中,都有唯一不变的内存地址,所以你在程序哪里都能访问,只要你声明要使用其名字即可。
  2. 然后cpu会从只读代码段开始读取命令执行。

那局部变量在哪里呢?

局部变量的生命周期

当程序调用函数时,cpu首先会从代码段读取相应函数指令,并在寄存器用来做局部变量的存储和相关运算。注意这里是在寄存器,所以当函数调用结束,寄存器又会加载新的指令和数据来覆盖局部变量,所以说局部变量的生命周期是在函数调用完就会结束。

函数栈空间

然而我们知道,寄存器的空间是有限的,当我们的局部变量比较大,或者是函数又反复嵌套调用函数,我们可能就需要内存空间来保存我们的局部变量和函数调用。

很明显,函数的嵌套调用很符合栈“先进后出”的特性,所以采用内存栈。借这个机会,我们来谈谈为什么递归开销比较大,因为他要在内存空间创建很多函数副本,cpu对内存访问速度的访问速度对寄存器的比慢得多。

posted @ 2021-10-18 20:40  xfw121  阅读(187)  评论(0)    收藏  举报