【C++】(九)作用域和生命期

it2023-04-17  71

文章目录

作用域和生命期1 局部变量和全局变量1.1 局部变量1.2 全局变量 2 作用域3 生命期4 内部函数与外部函数5 头文件与工程文件

作用域和生命期

1 局部变量和全局变量

1.1 局部变量

在函数内部或复合语句中(简称区域)定义的变量,称为局部变量 (local variable),又称为内部变量。 下列变量是局部变量

在一个函数内部定义的变量函数的形式参数在某个复合语句中定义的变量

局部变量的说明: (1)局部变量只能在定义它的区域及其子区域中使用。

(2)在同一个区域中不能定义相同名字的变量。

(3)在不同区域中允许定义相同名字的变量,但本质上它们是不同的变量

(4)如果一个变量所处区域的子区域中有同名的变量,则该变量 在子区域无效,有效的是子区域的变量,称为定义屏蔽。

1.2 全局变量

在源文件中,但在函数外部定义的变量,称为全局变量(global variable),全局变量的有效区域是从定义变量的位置开始到源文件结束。 函数之间数据传递尽管可以利用全局变量,但这样一来也导致两个 函数彼此分不开,违背模块化的原则,所以结构化程序设计提倡少用或不用全局变量。

有效无效

2 作用域

C++的实体通常有三类:

变量或对象。例如变量、数组等;函数;类型。包含结构体类型、共用体类型、类类型。

作用域是程序中的一段区域。在同一个作用域上,C++程序中每个名字都与唯一的实体对应;如果在不同的作用域上,程序中可以多次使用同一个名字,对应不同作用域中的不同实体。

作用域分有: (1)文件作用域 (2)函数作用域(function scope) (3)块作用域(block scope) (4)类型声明作用域(declaration scope) (5)函数原型作用域(function prototype scope)

实体在作用域内可以使用称为可见(visible),又称有效。可见的 含义是指实体在作用域上可以使用。 下面给出C++实体可见规则 (1)规则一。同一个作用域内不允许有相同名字的实体,不同作 用域的实体可以有相同名字。 (2)规则二。实体在包含它的作用域内,从定义或声明的位置开始,按文件行的顺序往后(往下)直到该作用域结束均是可见的, 包含作用域内的所有子区域及其嵌套。 (3)规则三。若实体A在包含它的作用域内的子区域中出现了相同 名字的实体B,则实体A被屏蔽。 第二行定义的c在第三行开始的子区域中被屏蔽了

(4)规则四。可以使用extern声明将变量或函数实体的可见区域 往前延伸,称为前置声明(forward declaration)。 extern声明变量实体的形式为:

extern 类型 变量名, ......

extern声明函数原型的形式为:

extern 返回类型 函数名(类型1 参数名1, ......); extern 返回类型 函数名(类型1,......);

(5)规则五。在全局作用域中,变量或函数实体若使用static修饰, 则该实体对于其他源文件是屏蔽的,称为私有的(private)。 static修饰变量实体的形式为:

static 类型 变量名[=初值], ......

static修饰函数原型的形式为:

static 返回类型 函数名(类型1 参数名1, ......); static 返回类型 函数名(类型1, ......) ;

FILE1.CPP

FILE2.CPP

3 生命期

C++中,每个名字都有作用域,即可以使用名字的区域,而每个对 象都有生命期(lifetimes),即在程序执行过程中对象存在的时间

1 动态存储 动态存储(dynamic storage duration)是指在程序运行期间,系统为对象动态地分配存储空间。动态存储的特点是存储空间的分配和释放是动态的,要么由函数调用来自动分配释放,要么由程序指令来人工分配释放,这个生命期是整个程序运行期的一部分。 动态存储的优点是对象不持久地占有存储空间,释放后让出空闲空 间给其他对象的分配。

动态存储在分配和释放的形式有两种,一种是由函数调用来自动完 成的,称为自动存储(automatic storage),一种是由程序员通过 指令的方式来人工完成的,称为自由存储(free storage)。

2 静态存储 静态存储(static storage duration)是指对象在整个程序运行期持久占有存储空间,其生命期与程序运行期相同。静态存储的特点是对象的数据可以在程序运行期始终保持直到修改为止,或者程序结束为止,静态存储的分配和释放在编译完成时就决定好了。 现代程序设计的观点是,除非有必要尽量少地使用静态存储。

3 自动对象 默认情况下,函数或复合语句中的对象(包含形参)称为自动对象 (automatic objects),其存储方式是自动存储,程序中大多数对 象是自动存储。

auto 类型 变量名[=初值], ......

4 寄存器变量 C++语言允许用CPU的寄存器来存放局部变量,称为寄存器变量。 在局部变量前加上register存储类别修饰来定义的,其形式为:

register 类型 变量名[=初值], ......

5 静态局部对象 在局部对象的前面加上static存储类别修饰用来指明对象是静态局 部对象(static local object),一般形式为:

static 类型 变量名[=初值] , ......

4 内部函数与外部函数

内部函数 函数本质上是全局的,在多文件的程序中,在连接时会检查函数在全局作用域内是否名字唯一,如果不是则出现连接错误。 在函数定义前加上static修饰,则函数称为内部函数,定义形式为: 按照前面的实体可见规则,内部函数仅在包含它的文件中有效。

之所以使用内部函数的原因是该函数逻辑上仅限定在一个文件中使用,其他文件不会用到。而且希望连接检查时永远不可能出现该函数名不唯一的连接错误,这在多人编写同一个程序的软件开发模式中是常用的策略。

外部函数 在函数定义前加上extern声明,则函数称为外部函数,定义形式为:

C++中所有的函数本质上都是外部函数。因此,上面的extern都可 以省略。

5 头文件与工程文件

为什么要使用头文件呢? 我们现在已经知道,如果是多文件结构程序,欲在文件中调用别的文件中的函数,需要有函数的声明,而且每个文件均是如此。如果是函数声明比较多的情况下,在每个文件中都写上函数声明不是好办法,很难管理。例如:某个函数定义有变动,那么所有含有这 函数声明的调用文件都需要找出来,逐一修改。

使用头文件可以解决这个问题,其工作原理是通过将每个源文件中外部函数的函数声明等信息集中写到一个文件中,称为头文件(有别于源文件),而别的源文件只需用文件包含命令将这个头文件包含,则编译时编译器自然就有了函数声明。

# include<>

在系统路径中找头文件

#include""

除了在系统路径中找,还要到用户路径(工程所在路径)找

工程文件 多文件结构程序在编译时需要工程文件来管理,不同的编译器有不 同的工程文件格式。

将文件分门别类地管理。

例子:

最新回复(0)