作用域—可见性—生存期(精)
《面向对象程序设计》辅导四

《面向对象程序设计》辅导四第六章 简单程序设计学习要点:一个真正的C++程序是由多个文件组成的。
在开发的过程中,会形成多个程序文件和多个头文件。
多文件结构可以提高程序的可读性、提高程序的开发效率。
学习要求:理解多文件结构,能在程序设计中合理利用多文件来进行模块划分。
能正确使用外部存储类型和静态存储类型。
理解编译预处理的概念,能在程序中合理使用#include 预处理指令,看懂#define 、#if 、#ifndef 、#else 、#undef 、#elif 等指令。
理解标识符的三种生命期:静态、局部和动态生命期,能指出给定程序中标识符的生命期。
能综合运用头文件、外部变量、静态变量来组织多文件结构的程序。
学习方法引导:从多文件结构入手,学习如何编制C++程序,理解C++程序的整体结构。
掌握几个重要概念。
结合实例来理解一个由多文件组成的程序的开发过程。
学习内容:我们知道,用VC 设计软件时首先要建立一个工程文件,在这个工程文件中指定了该工程用到的所有文件,这其中包含了所有C++程序文件。
C++程序是由许多函数组成的,函数是由语句组成的。
如下图所示。
在设计程序时,需要定义大量标识符,对标识符的操作是程序设计的关键。
标识符一经定义就有了其作用范围,它在某些范围内是可见的,并不是定义之后都能使用。
特别是在多文件结构中,标识符的作用范围除了块级、函数级、还包括文件级和程序级;全局变量不再只是文件级变量,而又分为外部变量和静态全局变量;函数则又分为外部函数和静态函数等。
因此在设计多文件结构的C++程序时,有着比单文件结构更复杂的特性。
一、多文件结构在设计大型系统时,一般都由多个程序设计人员合作完成,每个程序员完成一部分程序,并以文件的形式存储起来,这样一个工程就包含多个程序文件。
C++支持多文件结构,即允许一个工程文件中建立多个程序文件。
多文件结构与单文件有比较类库自定义包含文件 。
包含main 函数的主文件:main 函数是程序的入口,每个工程只有一个main 函数。
(整理)第04章 变量的存储类型

第4章变量的存储类型4.1 概述C语言中的变量具有两种属性:根据变量所持有数据的性质不同而分为各种数据类型;根据变量的存储方式不同而分为各种存储类型.变量的数据类型决定了该变量所占内存单元的大小及形式;变量的存储类型规定了该变量所在的存储区域,因而规定了该变量作用时间的长短,即寿命的长短,这种性质又称为"存在性".变量在程序中说明的位置决定了该变量的作用域,即在什么范围内可以引用该变量,"可引用"又称为"可见",所以这种性质又称为"可见性".计算机的内存和CPU中的寄存器都可以存放数据,变量究竟存放在何处则由存储类来决定.存储类型用来说明变量的作用域,生存期,可见性和存储方式.下面解释几个概念:1 作用域:是该变量在其上有定义的程序部分,通俗的说,即该变量起作用的某个程序区域。
2 变量的生存期:是指它从产生到消亡的存在时间,即变量从定义开始到它所占有的存储空间被系统收回为止的这段时间。
3 变量的可见性的含义:在某个程序区域,可以对变量进行访问(或称存取)操作,我们则称该变量在该区域为可见的,否则为不可见的。
再引入几个概念:4 全局变量和局部变量在一个函数内部或复合语句内部定义的变量叫内部变量,又称为"局部变量"。
在函数外定义的变量称为外部变量,又称为"全局变量"。
如:int x ;void main( ){int a, b;float c;……..}x 定义在函数外,是全局int 型变量a,b定义在main()函数内是局部int 型变量c 定义在main()函数内是局部float 型变量6 动态存储变量和静态存储变量。
在程序运行期间,所有的变量均需占有内存,有的是临时占用内存,有的是整个程序运行过程中从头到尾占用内存。
对于在程序运行期间根据需要进行临时性动态分配存储空间的变量称为"动态存储变量",对于在程序运行期间永久性占用内存的变量称为"静态存储变量".一个正在运行的程序可将其使用内存的情况分为如下三类(如下图):程序代码区: 程序的指令代码存放在程序代码区。
第19章 生存期、作用域与可见域

19.3.2 使用举例
来看一个计算的近似值的例子,求解的一个近似公式如下: 为了达到较高精度,需要进行的循环次数较多,为提高效 率,可将循环控制变量定义为寄存器变量,如所示:
19.4 extern变量
extern变量又称全局变量,放在静态存储区,所 谓全局,是说该变量可以在程序的任意位置使用, 其作用域是整个程序代码范围内,和auto变量不 同的是,extern变量有定义和声明之分.
19.1.4 作用域与可见域
在程序代码中,变量有效的范围(源程序区域)称为作用域,能对变量, 标识符进行合法的访问的范围(源程序区域)称为可见域,可以这样说, 作用域是变量理论上有效的区域,而可见域是变量实际有效的区域,可见 域是作用域的子集. 可以将C语言的作用域分为以下几类: (1)块作用域 自动变量(auto,register)和内部静态变量(static)具有块作用域, 在一个块内声明的变量,其作用域从声明点开始,到该块结束为止.函数 定义中声明的形参,其作用域限定在该函数体内,与其他函数中声明的同 名变量不是一回事,允许在不同的函数中使用相同的变量名,编译器将为 这些变量分配不同的存储单元,不会混淆. (2)文件作用域 外部静态变量(static)具有文件作用域,从声明点开始到文件末尾,此 处所指的文件是编译基本单位—c文件. (3)全局(程序)作用域 全局变量(extern)具有全局作用域,只要在使用前对其进行声明,便可 在程序(由若干个文件组成)的任意位置使用全局变量.
19.4.1 全局变量定义
全局变量定义的基本格式为: extern 类型 变量名 = 初始化表达式 ; 此时,初始化表达式不可省略,此指令通知编译器在静态存储区 中开辟一块指定类型大小的内存区域,用于存储该变量. 下列语句创建了一个初始值为100的int型全局变量m: extern int m=100; C语言规定,只要是在外部,即不是在任何一个函数内定义的变量, 编译器就将其当作全局变量,无论变量定义前是否有extern说明 符.也就是说,只要在函数外部书写下述形式即可: int m=100; 当全局变量定义时,当且仅当省略了extern时,初始化表达式才 可省略,系统默认将其初始化为0,对于定义的全局数组或结构, 编译器将其中的每个元素或成员的所有位都初始化为0.
第18讲 局部变量 全局变量和存储分类 局部变量作用域和生存期

局部变量 全局变量和存储分类 局部变量及其作用域和生存期
第八章 用户标识符的作用域和存储类
8.1 局部变量,全局变量和存储分类
1. 用户标识符的作用域 作用域 在C语言中,由用户命名的标识符都有一个有 效的作用域.所谓"作用域"是指程序中的某一 部分,只有在这一部分中,该标识符才是有定义 的,即只有在这个域中才能使用该标识符. 例如,在某一函数内定义的变量,只能在该 函数内进行使用.显然,变量的作用域与其定义 语句在程序中出现的位置有直接的关系.由此可 以划分为局部变量和全局变量.
2. 局部变量 例 不同函数中同名变量 例 复合语句中变量
Ch7_103.c Ch7_102.c
局部变量 float f1(int a) 5 #define N { main() int b,c; 定义:在函数内定义,只在本函数内有效 main() a,b,c有效 a,b; { int{ …….i; 说明: } int a=3; int a[N]={1,2,3,4,5}; b=4; ①在main函数中定义的变量只能在main函数中有效 printf("main:a=%d,b=%d\n",a,b); char f2(int x,int y) for(i=0;i<N/2;i++) ②不同函数中的同名变量,占不同的内存单元 sub(); i,j; temp; { { int int x,y,i,j有效 printf("main:a=%d,b=%d\n",a,b); ③函数的形参属于局部变量 …… temp=a[i]; } } ④可以定义只在某个复合语句中有效的变量 a[i]=a[N-i-1]; sub() main() a[N-i-1]=temp; { int a,b;m,n; { int } m,n有效 a=6;……. b=7; for(i=0;i<N;i++) } printf("sub:a=%d,b=%d\n",a,b); printf("%d ",a[i]); } }
作用域—可见性—生存期(精)

程序的运行结果为: First time output: 0:0:0 First time output: 8:30:30
数据与函数
数据存储在局部对象中,通过参数传 递实现共享——函数间的参数传递。
数据存储在全局对象中。
例
将数据和使用数据的函数封装在类中。
例
前一页
休息
20
静态成员
静态数据成员
前一页
休息
9
例
对 象 的 生 存 期
#include<iostream.h> int i=5; //文件作用域 int main( ) { cout<<"i="<<i<<endl; return 0; } i具有静态生存期
前一页 休息 10
动态生存期
对 象 的 生 存 期
块作用域中声明的对象是动态生存期 的对象(习惯称局部生存期对象)。
#include<iostream.h> class Application { public: static void f( ); static void g( ); private: static int global; }; int Application::global=0; void Application::f( ) { global=5;} void Application::g( ) { cout<<global<<endl;}
作用域和可见性

:作用域和可见性开始鸡啄米就要讲讲C++程序设计中必知的一些结构和语法的知识点。
这些都是很基础但是很有必要掌握的知识,能够很好的利用这些知识就表示你有一些内功了哦。
这些必知的知识包括作用域、可见性和生存期,还有局部变量、全局变量、类的数据成员、静态成员及友元和数据等。
这一讲鸡啄米会给大家详细讲讲作用域和可见性。
作用域是用来表示某个标识符在什么范围内有效,可见性是指标识符是否可见,可引用。
1. 作用域作用域是这样一个区域,标识符在程序的这个区域内是有效的。
C++的作用域主要有四种:函数原型作用域、块作用域、类作用域和文件作用域。
a. 函数原型作用域函数原型大家还记得吗?比如:void fun(int x);这个语句就是函数原型的声明。
函数原型声明中的形参的作用范围就是函数原型作用域。
fun函数中形参x有效的范围就在左、右两个括号之间,出了这两个括号,在程序的其他地方都无法引用x。
标识符x的作用域就是所谓的函数原型作用域。
函数原型如果有形参,声明时一定要有形参的类型说明,但是形参名比如x可以省略,不会对程序有任何影响,一般为了程序可读性好,我们一般都写上一个容易理解的形参名。
函数原型作用域是最小的作用域。
b. 块作用域c. void fun(int x){int a(x); // a的作用域开始cin>>a;if (a>0){int b; // b的作用域开始......} // b的作用域结束} // a的作用域结束d. 在fun的函数体内声明了整型变量a,又在if语句的分支内声明了变量b,a和b都具有块作用域,但是它们的块作用域并不同。
a的作用域从其声明处开始,到其所在块的结束处也就是整个函数体结束的地方为止,b的作用域是从b声明处开始到其所在块结束也就是if分支体结束0的地方为止。
c.类作用域假设有一个类A,A中有一个数据成员x,x在A的所有函数成员中都有效,除非函数成员中也定义了一个名称为x的变量,这样的x就具有类作用域。
变量的作用域和生存期PPT课件

2.静态局部类型
定义局部变量时,使用Static修饰,可以在不改变局部变量的可见域的前提下, 使变量成为静态的,即当函数撤销后,变量的值还保留。或者说,这些变量的生存期 是永久的,只是在变量的作用域外是不可见的。这样,避免了全局变量的值可以被多 处修改将引起的副作用,又可以使函数基于前一次调用的值的基础上工作。
【例4-9】演示全局变量的作用域
• Int p=1,q=5; • Float f1(int a) •{ • int b,c; • ……. •} • Char c1,c2; • Char f2(int x,int y) •{ • int i,j; • ……. •} • Int main(void) •{ • Int m,n; • ……. •}
main( ) {int k=4,m=1,p;
p=func(k,m); printf(“%d,”,p); p=func(k,m); printf(“%d\n”,p);}
func(a,b) int a,b; {static int m=0,i=2; i+=m+1; m=i+a+b; return(m);}
4.5.2 C语言中变量的存储类型
根据变童的作用域将变量分为全局变量和局部变量,根据变量的生存期将变量分 为动态变量和静态变量。因此,C语言根据作用域和生存期将变量整合成四种存储类型。
(1)局部自动类型。在函数内部用标识符auto或register 声明。 (2)静态局部类型。在函数内部,使用Static声明。 (3)静态全局类型。在函数外部,使用Static。声明,也称为静态外部变量。 (4)全局类型。不需要标识符声明。在函数外部直接声明即可,通常称为外部变 量。
1. AUTO 存储类型和REGISTER 存储类型
第6章-程序结构

一 、<iostream>和<iostream.h>格式不一样 前者 没有后缀,实际上,在你的编译器include文件夹里面可以 看到,二者是两个文件,打开文件就会发现,里面的代码是 不一样的。 后缀为.h的头文件c++标准已经明确提出不支 持了,早些的实现将标准库功能定义在全局空间里,声明在 带.h后缀的头文件里。c++标准为了和C区别开,也为了正 确使用命名空间,规定头文件不使用后缀.h。 因 此,当使 用<iostream.h>时,相当于在c中调用库函数,使用的是全 局命名空间,也就是早期的c++实现;当使用< iostream> 的时候,该头文件没有定义全局命名空间,必须使用 namespace std;这样才能正确使用cout。
静态函数有两个效果:1、它允许其他源文件建立并使用同名的函数, 而不相互冲突,在大的编程项目中是一个优势。2、声明为静态的函数不能 被其他源文件所调用,因为得不到它的名字。
【 6.3 作用域】
作用域是标识符在程序中有效地范围,标识符的引入与声明有关,作用 于开始于标识符的声明处。 C++有四种作用域的范围: 1、局部作用域 2、函数作用域 3、函数原型作用域 4、文件作用域
本章介绍C++的程序结构。所有的C++程序都是由一个或多个函数构成的。 一个C++程序可以由一个或多个包含若干函数定义的源文件组成。C++编 译器和链接器把构成一个程序的若干源文件有机地联络在一起,最终产生 可执行程序。
一般具有应用价值的程序由多个源文件组成。其中只有一个源文件具有 main( )函数,其他的文件不能含有主函数。
作用域(全局作用域和局部作用域)

作⽤域(全局作⽤域和局部作⽤域)作⽤域---->作⽤范围(作⽤域⼜叫作⽤范围,在什么范围内有效)⼀、全局作⽤域:包含内置名称空间、全局名称空间 1.存活周期:该范围内的名字全局存活(除⾮被删除,否则在整个⽂件执⾏过程中存活) 2.全局有效,在任意位置都可以使⽤,被所有函数共享⼆、局部作⽤域:包含局部名称空间 1.存活周期:该范围内的名字临时存活(在函数调⽤时临时⽣成,调⽤结束后就释放) 2.局部有效,只能在函数内使⽤三、global与nonlocal 1.如果在局部中想要修改全局的名字所对应的值,那么就需要global,主要针对不可变类型 ⽰例1:global主要是针对不可变类型 x = 100 # 全局名称空间(也是全局作⽤域) def func(): global x # 使⽤global,表⽰修改全局作⽤域中的x x = 200 # 在函数内,表⽰为局部名称空间(也是局部作⽤域) func() print(x) # 输出结果为:200,x=200为局部作⽤域,也是局部名称空间,这⾥使⽤了global(表⽰修改全局中的),所以修改了全局中的x = 100 ⽰例2:⽰例1中主要是针对不可变类型的,⽰例2针对可变类型 x = [] # 全局名称空间,声明的是⼀个数组 def func(): a.append(111) # 直接对数组进⾏添加操作,对于可变类型的就不⽤使⽤global了,因为在函数中可以直接对可变类型进⾏操作 func() print(x) # 输出结果为:[111] 2.修改函数外层函数包含的名字对于的值(与global⼀样针对不可变类型),这是需要使⽤nonlocal ⽰例1:针对不可变类型 x = 100 # 全局名称空间 def func(): x = 200 # 局部名称空间 def func1(): nonlocal x # 表⽰修改该层函数上层函数的x,如果有三层函数,找上层表⽰先找第⼆层,如果没有找到则会找第⼀层,如果还没有就会报错,不会找全局 x = 300 func1() print(x) # 输出结果为:300,x =300为局部作⽤域,这⾥使⽤了nonlocal(表⽰修改func1上⼀层中的名称对应的值),所以修改了x=200的值 func() ⽰例2:针对可变类型时,与global⼀样的,直接进⾏修改即可,不适⽤nonlocal。
最难的函数知识点总结

最难的函数知识点总结1. 函数的定义和调用在编程中,函数是一种用来完成特定任务的代码块。
函数通常包括函数名、参数列表和函数体。
函数的定义告诉编译器如何执行该函数,而函数的调用告诉编译器何时执行该函数。
在定义函数时,需要指定函数名和参数列表,并且可以选择性地指定返回类型。
在调用函数时,需要指定函数名和参数列表的实际值,以便执行函数体中的代码。
2. 函数的参数传递函数的参数传递是指向函数传递参数的方式。
在函数调用中,可以通过值传递、引用传递或指针传递来传递参数。
值传递是将参数的值复制一份并传递给函数,这样函数可以使用参数的副本进行操作。
引用传递是将参数的地址传递给函数,这样函数可以直接操作参数的值。
指针传递是将参数的指针传递给函数,这样函数可以通过指针来访问参数的值。
不同的参数传递方式有不同的影响和使用场景,需要根据实际情况进行选择。
3. 函数的返回值函数可以返回一个值,也可以不返回任何值。
如果函数需要返回一个值,需要在函数定义时指定返回类型,并且在函数体中使用`return`语句返回具体的值。
在函数调用时,可以使用返回值来获取函数的结果并进行后续的操作。
如果函数不需要返回任何值,可以将返回类型指定为`void`,并且在函数体中不使用`return`语句。
4. 函数的重载函数的重载是指在同一个作用域内定义多个同名函数的行为。
每个同名函数具有不同的参数列表或参数类型,以便在函数调用时根据参数匹配来确定具体调用哪个函数。
函数的重载可以提高代码的复用性,并且可以根据不同的需求来定义不同的函数。
在函数重载中,需要注意函数名称和参数列表的唯一性,以避免混淆和错误。
5. 函数的嵌套调用函数的嵌套调用是指在一个函数中调用另一个函数。
通过函数的嵌套调用,可以将复杂的问题分解成多个简单的子问题,并且可以实现代码的模块化和重用。
在函数的嵌套调用中,需要注意函数的调用顺序、参数的传递和返回值的处理,以保证程序的正确性和效率。
03-作用域与存储类别

f函数中的 自动局部
变量k
int main()
main函数 中的自动 局部变量k
{ int k=2; //auto int =2;
cout<<f(k)<<endl; cout<< f(k)<<endl; system("pause"); return 0;
}
问题一: f函数中的k和main函数中的k会冲突吗?
}
扩展i的 作用域
int i=5; int main() { int j=20;
cout<<j; fun(); system("pause"); return 0; }
全部变量示例
#include "iostream“ using namespace std; int m=10; void f1(int n)
全局变量m
形参n(局 部变量)
问题四: 程序的输出结果是什么?
{ n=2*n;m=m/3; } //m=3,n=4(形参n)
int n;
void f2()
全局变量n
开始执行分程序就生成,分程序执行结束就消亡 4 初始化:可以初始化,缺省值为随机值
自动局部变量示例
#include "iostream“
using namespace std;
int f(int x) { x++;
int k=5; k++;
形参也是 局部变量
//auto int k=5;
return x+k; }
作用域与存储类别
作用域与生存期的概念
➢作用域(可见性): 在什么范围内可以被访问
static作用:静态变量的生存周期和作用域

static作⽤:静态变量的⽣存周期和作⽤域⾸先要理解⽣存周期与作⽤域的区别:⽣存周期: 变量从定义到销毁的时间范围。
存放在全局数据区的变量的⽣存周期存在于整个程序运⾏期间,⽽存放在栈中的数据则随着函数等的作⽤域结束导致出栈⽽销毁,除了静态变量之外的局部变量都存放于栈中。
作⽤域: 变量的可见代码域(块作⽤域,函数作⽤域,类作⽤域,程序全局作⽤域)。
static变量是指静态的变量,不管是在全局还是局部声明的static变量都存放于程序的全局变量区域,所以它的⽣命周期是从程序开始到程序结束。
但是static变量的作⽤域并不等同于它的⽣存周期,它的作⽤域决定于它被定义的位置。
可以认为static变量的作⽤域<=⽣存周期。
举⼀个局部声明的例⼦。
在函数test中声明静态变量i:void test(){int m=3;static int i=5;}局部变量m存放在栈中,当test函数结束,m将被销毁;静态变量i不存放在栈中,⽽是存放于程序的全局变量区域,因此随着函数test的结束,它并不随着出栈操作⽽被销毁,它的⽣存周期存在于程序的整个运⾏期;然⽽m和i的作⽤域都仅存在于test函数中它们的定义之后,即test调⽤结束之后,m和i就不再可⽤,但是i仍存在于内存之中。
再举⼀个全局声明的例⼦。
在⽂件A 中定义静态变量j:int n=3; //默认为externstatic int j=5; //声明为static全局变量和静态变量j都存放于程序的全局数据区域,它们的⽣存周期都是程序的整个运⾏期,但是n的作⽤域为全局作⽤域,可以通过extern在其他⽂件中使⽤,⽽j只能在⽂件A中使⽤,例如在⽂件B中:extern int n; //okextern int j; //error: j在⽂件B中不可见int a=n;//ok:但这⾥有个初始化先后的问题,具体参见参考⼀int b=j;//error也就是说,在声明全局的static变量时,static没有改变它的⽣存周期,也即存储位置(因为全局变量本来就存储在全局数据域),⽽是将变量的作⽤域限制在当前⽂件中。
c++8

例5-6 使用友元函数计算两点距离 友 元
#include <iostream> #include <cmath> using namespace std; class Point //Point类声明 类声明 { public: //外部接口 外部接口 Point(int xx=0, int yy=0) {X=xx;Y=yy;} int GetX() {return X;} int GetY() {return Y;} friend float Distance(Point &a, Point &b); private: //私有数据成员 私有数据成员 int X,Y; };
19
void B::Set(int i) { a.x=i; } void B::Display() { a.Display(); } main() { B b1; b1.Set(4); b1.Display(); }
39
友元关系是单向的
如果声明B类是 类的友元 如果声明 类是A类的友元,B类的 类是 类的友元, 类的 成员函数就可以访问A类的私有和保护 成员函数可以访问 类的私有和保护 数据, 类的成员函数却不能访问B 数据,但A类的成员函数却不能访问 类的成员函数却不能访问 类的私有、保护数据。 类的私有、保护数据。 友元是不能传递的
36
友元类
友 元
若一个类为另一个类的友元, 若一个类为另一个类的友元,则此类 的所有成员都能访问对方类的私有成 员。 声明语法: 声明语法:将友元类名在另一个类中 使用friend修饰说明。 修饰说明。 使用 修饰说明
18
友元类举例
友 元
#include <iostream.h> class A { friend class B; public: void Display() {cout<<x<<endl;} private: int x; }; class B { public: void Set(int i); void Display(); private: A a; };
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
前一页
休息
9
例
对 象 的 生 存 期
#include<iostream.h> int i=5; //文件作用域 int main( ) { cout<<"i="<<i<<endl; return 0; } i具有静态生存期
前一页 休息 10
动态生存期
对 象 的 生 存 期
块作用域中声明的对象是动态生存期 的对象(习惯称局部生存期对象)。
休息 3
前一页
类和文件作用域
作 用 域 与 可 见 性
类作用域作用于特定的成员名,类及 其对象有特殊的访问和作用域规则。
不在前述各个作用域中出现的声明, 具有文件作用域,这样声明的标识符 的作用域开始于声明点,结束于文件 尾。
前一页
休息
4
可见性
作 用 域 与 可 见 性
可见性是从对标识符的引用的角度来谈 的概念 可见性表示从内层作用域向外层作用域 “看”时能看见什么。 如果标识在某处可见,则就可以在该处 引用此标识符。
休息
前一页
7
对象的生存期
对象从产生到结束的这段时间就是
它的生存期。在对象生存期内,对象将
保持它的值,直到被更新为止。
前一页
休息
8
静态生存期
对 象 的 生 存 期
这种生存期与程序的运行期相同。 在文件作用域中声明的对象具有这种 生存期。 在函数内部声明静态生存期对象,要 冠以关键字static 。
文件作用域 类作用域
块作用域
前一页 休息 5
可见性
作 用 域 与 可 见 性
标识符应声明在先,引用在后。
在同一作用域中,不能声明同名的标识符。 如果某个标识符在外层中声明,且在内层中 没有同一标识符的声明,则该标识符在内层 可见。
对于两个嵌套的作用域,如果在内层作用域 内声明了与外层作用域中同名的标识符,则 外层作用域的标识符在内层不可见。
radius 的作用域仅在于此, 不能用于程序正文其它地 方,因而可有可无。
前一页
休息
2
块作用域
作 用 域 与 可 见 性
在块中声明的标识符,其作用域自声明处 起,限于块中,例如: void fun(int a) { int b(a); cin>>b; b的作用域 if (b>0) { int c; c的作用域 ...... } }
本章主要内容
作用域与可见性 对象的生存期 数据与函数 静态成员 共享数据的保护 友元 编译预处理命令 多文件结构和工程
前一页 休息 1
函数原形的作用域
作 用 域 与 可 见 性
函数原型中的参数,其作用域始于 "(",结束于")"。 例如,设有下列原型声明:
double Area(double radius);
休息 6
前一页
例 5.1
作 用 域 与 可 见 性
#include<iostream.h> int i; //文件作用域 int main( ) { i=5; { int i; //块作用域 i=7; cout<<"i="<<i<<endl; //输出7 } cout<<"i="<<i; //输出5 return 0; }
开始于程序执行到声明点时,结束于 命名该标识符的作用域结束处。
前一页
休息
11
例
对 象 的 生 存 期
#include<iostream.h> void fun( ); void main( ) 运行结果: { fun( ); i=6, a=2 fun( ); } i=6, a=3 void fun( ) { static int a=1; i是动态生存期 int i=5; a++; a是静态生存期 i++; cout<<"i="<<i<<",a="<<a<<endl; }
休息 16
前一页
//时钟类成员函数实现 Clock::Clock( ) //构造函数 { Hour=0; Minute=0; Second=0; } void Clock::SetTime(int NewH, int NewM, int NewS) { Hour=NewH; Minute=NewM; Second=NewS; } void Clock::ShowTime( ) { cout<<Hour<<":"<<Minute<<":"<<Second<<endl; }
对 象 的 生 存 期
#include<iostream.h> class Clock //时钟类声明 {public: //外部接口 Clock( ); void SetTime(int NewH, int NewM, int NewS); //三个形参均具有函数原型作用域 void ShowTime( ); ~Clock( ){} private: //私有数据成员 int Hour,Minute,Second; };
休息 12
前一页
例5-2 变量的生存期与可见性
对象 的 生 存 期
#include<iostream.h> int i=1; // i 为全局变量,具有静态生存期。 void main(void) { static int a; // 静态局部变量,有全局寿命,局部可见。 int b=-10; // b, c为局部变量,具有动态生存期。 int c=0; void other(void); cout<<"---MAIN---\n"; cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl; c=c+8; other( ); cout<<"---MAIN---\n"; cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl; i=i+10; other( ); }
休息 13
前一页
void other(void) { static int a=2; static int b; // a,b为静态局部变量,具有全局寿命,局部可见。 //只第一次进入函数时被初始化。 int c=10; // C为局部变量,具有动态生存期, //每次进入函数时都初始化。 a=a+2; i=i+32; c=c+5; cout<<"---OTHER---\n"; cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl; b=a; }
运行结果: ---MAIN--i: 1 a: 0 b: -10 c: 0 ---OTHER--i: 33 a: 4 b: 0 c: 15 ---MAIN--i: 33 a: 0 b: -10 c: 8 ---OTHER--i: 75 a: 6 b: 4 c: 15
例5-3 具有静态、动态生存期对象的时钟程序