第5章(作用域和存储类型)

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

21
5.1.3 动态存储方式与静态存储方式
• 按照变量存在的时间 ( 即生存期 ) 的不同,变量可 分为两类: – 动态存储方式存储的变量(动态变量) – 静态存储方式存储的变量(静态变量) • C++的存储空间分为 ① 代码区:存放可执行程序的程序代码; ② 静态存储区:存放静态变量和全局变量; ③ 栈(Stack)区:存放动态局部变量; ④ 堆(Heap)区:存放new和malloc()申请的动态内 存。(详见8.4节)。 栈区和堆区统称为动态存储区。 22
25
5.2.1 自动类型(auto)
1. 概念 用自动类型关键字auto说明的变量称为自动变量。 2. 定义格式: auto 数据类型 变量名; 注:auto只能修饰局部变量,不能修饰全局变量。 3. 特性: – 自动变量是动态局部变量,具有局部作用域特点, 存放在动态存储区。 – auto说明符可以省略,缺省时默认为auto型 – 系统以栈方式为 auto变量分配内存空间,在变量 作用域结束后,栈空间由系统进行自动回收。 – 如果定义自动变量时未初始化,则其值默认为随 26 机数。
【例5.1】 输入两数,按从大到小的顺序保存,并 输出结果。 #include<iostream.h> void main( ) { int a,b; //a, b的作用域从此开始 cout<<"输入两整数:"<<endl; cin>>a>>b; cout<<"a="<<a<<'\t'<<"b="<<b<<endl; if(b>=a) { int t; //t具有块作用域,t的作用域从此开始 t=a; a=b; b=t; //交换a,b的值 } //t的作用域到此结束 cout<<“t=”<<t<<endl; //错误,t已经无效 cout<<"a="<<a<<'\t'<<"b="<<b<<endl; 4 } //a,b的作用域到此结束
6
3.函数声明作用域 • 函数声明中的形参具有函数声明作用域,其作用 域开始于函数声明的左括号,结束于函数声明的 右括号。 例如,下面的函数声明: int max(int a, int b); //a,b作用域在括号内 • 正是由于形参不能被程序的其他地方引用,所以 通常函数声明时,只要声明形参个数和类型,形 参名可省略。
7
4.函数作用域 – 标号具有函数作用域,标号声明使该标识符 在函数内的任何位置均可使用。例如, void fun( ) { goto S; int x; cin>>x; { S: goto End; 标号S和End的作用域 } End: cout<<"OK"<<endl; } – 函数中定义的变量,包括形参和函数体中定义的 局部变量,作用域都在该函数内,也称作函数域。
13
2. 全局变量
• 在函数外部定义的变量称为全局变量。 • 全局变量的作用域从定义的位置开始直到本文件 的结束,具有文件作用域,它可为本文件中的函 数所共用。 • 全局变量可以在各个函数之间建立数据传输通道, 但滥用会破坏程序的模块化结构。 • 全局变量在编译时在全局数据区分配内存空间, 在未给出初始化值时系统自动初始化为0。
2
1. 局部作用域 当标识符的声明出现在有一对花括号括起来的一段 程序(块)内时,该标识符的作用域是从变量声明 处开始,在块结束处(即块的右花括号处)为止, 该作用域的范围具有局部性。局部作用域又称块作 用域。 例如, int fun(int x) //x的作用域从此开始 { int y; //y的作用域从此开始 y=x*x; …… } //x,y的作用域到此结束 3
5.1.2 局部变量与全局变量
根据作用域的不同,程序中的变量分为: • 局部变量 • 全局变量
10
1.局部变量
• 在函数或者块内定义的变量称为局部变量。 • 局部变量仅在定义它的函数或块内起作用,在这 个范围之外不能使用这些变量。 • 函数内部使用的局部变量包括形式参数和函数体 内定义的变量。 • 局部变量的特点: –局部变量在程序运行到它所在的函数或块时在 栈中建立,该函数或块执行完毕局部变量占有 的空间即被释放。 –局部变量在定义时若未初始化,其值为随机数。 程序中使用的绝大多数变量都是局部变量。
1.动态存储方式
• 动态变量:在程序执行过程中分配存储空间的变量。 • 动态存储区可以存放函数的参数、自动变量、函数调 用时的现场保护和返回值等。 • 以动态方式存储的数据,在函数调用时分配动态存储 空间,函数结束时释放这些空间,在程序执行过程中, 这种分配和释放都是动态的。 • 动态变量的生存期是定义动态变量的函数运行期。它 对存储空间的利用是动态的,其初值是每次为动态变 量分配存储空间后都要重新设置。 例如,同一个程序两次调用同一函数,每次为形参和 自动局部变量分配的存储空间可能不同,且自动变量 都要重新初始化。 23
17Βιβλιοθήκη Baidu
for(int i=1;i<10;i++) { x=rand( )%101+100; //再产生一个[100, 200]之间的随机数x cout<<setw(4)<<x; if(x > max) max = x; //若新产生的随机数大于最大数,则进行替换 if(x < min) min = x; // 若新产生的随机数小于最小数,则进行替换 } return max; } void main( ) { int m=find( ); cout<<endl<<"最大数:"<<m<<",最小数:" <<min<<endl; } 18
void fun3( ) { x=5; //为全局变量x赋值 } void main( ) { x = 2; // 在主函数中为全局变量x赋值 fun1(5); cout<<"main:"<<x<<endl; fun2( ); cout<<"main:"<<x<<endl; fun3( ); cout<<"main:"<<x<<endl; } 运行结果为: local variable x is 6 glocal variable x is 2 main:2 local variable x is 5 glocal variable x is 2 main:2 main:5
2. 静态存储方式
• 静态变量:在程序开始运行前就分配存储空间的 变量。 • 以静态存储方式存储的数据(全局变量和静态局 部变量)全部存放在静态存储区中,在程序开始 运行前就为其分配相应的存储空间,在程序的整 个运行期间一直占用,直到程序执行完毕后释放。 它的生存期就是整个程序的运行期。
24
5.2 变量的存储类型
8
5.类作用域 –类作用域是指类定义范围(包括类的声明部分和 相应成员函数实现整个范围)。在该范围内,类 的成员函数对数据成员有无限访问权限。
前4种作用域总结: • 文件作用域:从函数外标识符定义开始到文件结束 (可用extern进行扩展)。 • 函数作用域:从函数开始到函数结束。 • 块作用域(局部作用域):从块内变量定义开始到块 结束。 • 函数声明作用域:函数声明内部有效。 9
说明: (1)全局变量可以作为函数间数据联系的渠道。 但使用全局变量过多,会降低程序的清晰性。 (2)全局变量在程序的全部执行过程中都占用存储单 元,而不是仅在需要时才开辟空间。 (3)使用全局变量会降低函数的通用性。 (4)建议不在必要时不要使用全局变量。
16
【例5.2】编写一个函数实现同时返回10个数的最大和 最小值。 分析:一个函数只能返回一个值,所以可以使用全局 变量在函数之间传递另一个值。 #include <iostream.h> #include <math.h> #include <iomanip.h> #include <stdlib.h> int min; //全局变量min int find( ) { int max, x; x=rand( )%101+100; //产生一个[100, 200]之间的随机数x cout<<setw(4)<<x; max = x; min =x; //设定最大数和最小数
• 当具有块作用域的局部变量与具有文件作用域的 全局变量同名时,与局部变量同名的全局变量不 起作用,即局部变量优先。 • 可以通过“::”域运算符访问同名的全局变量。
19
【例5.3】全局变量和局部变量的同名使用示例。 #include <iostream.h> int x; // 定义全局变量 void fun1(int x) //函数func1( )有一个名为x的参数 { x++; cout<<"local variable x is "<<x<<endl; cout<<"glocal variable x is "<<::x<<endl; } void fun2( ) { int x; //函数func2( )中定义了一个名为x的局部变量 x=5; cout<<"local variable x is "<<x<<endl; cout<<"glocal variable x is "<<::x<<endl; 20 }

复合语句是一个块。复合语句中定义的变量, 作用域仅在该复合语句中。
5
2.文件作用域 • 文件作用域也称全局作用域。 • 定义在所有函数之外的变量,具有文件作用域。 • 文件作用域为从定义处到整个源文件结束。 • 文件中定义的全局变量和函数都具有文件作用域。 • 如果某个文件中说明了具有文件作用域的变量, 该文件又被另一个文件包含,则该标识符的作用 域延伸到新的文件中。例如,cin和cout是在头文 件iostream.h中说明的具有文件作用域的标识符, 它们的作用域也延伸到了使用 include 命令包含 iostream.h的文件中。
12
说明: (1) 主函数中定义的变量也只在主函数中有效。不会 因为在主函数中定义而在整个文件或程序中有效。 主函数也不能使用其他函数中定义的变量。 (2) 不同函数中可以使用同名的变量,它们代表不同 的对象,互不干扰。 (3) 在一个函数内的复合语句中定义的变量,只在本 复合语句中有效。 (4) 形式参数也是局部变量。
14
int a=1, b=5; //定义全局变量a,b float f1(int c) { int m,n x=12.34; //错误,x在此不能使用 …… } double x,y; //定义全局变量x,y a,b的作用范围 char f2(char c1, char c2) { int i,j; x,y的作用范围 } void main( ) { x=12.34; //正确 15 }
11
float f1(int a) //函数f1 { int b,c; b、c有效 a有效 …… } char f2(int x, int y) //函数f2 { int i,j; x、y有效 i 、 j 有效 …… } int main( ) //主函数 { int m,n; …… m、n有效 { int p,q; p、q有效 …… } }
第5章 作用域和存储类型
本章学习重点: • 标识符的作用域 • 局部变量、全局变量的概念及区别 • 变量的存储类型 • 编译预处理 • 程序的多文件组织的概念及使用
1
5.1 作用域
5.1.1 作用域分类
1. 作用域的概念 • 标识符的作用域指的是标识符的有效范围,即标 识符在程序中可引用的区域。 C++ 的标识符包含变量名、常量名、函数名、类 名、对象名等。 2. 作用域的种类 • 局部作用域 • 文件作用域 • 函数声明(原型)作用域 • 函数作用域 • 类作用域
• 每个变量有两个属性:数据类型和存储类型。 存储类型指的是数据在内存中存储的方式。 • 变量的存储类型分为四种 – 自动类型(auto) – 寄存器类型(register) – 静态类型(static) – 外部类型(extern) 其中,自动类型、寄存器类型的变量属于动态变量; 静态类型、外部类型的变量属于静态变量。
【例5.4】使用自动变量的示例。 #include <iostream.h> void main( ) { int x=5,y=10; //自动变量x,y,省略auto for (int k=1;k<=2;k++) { auto int m=0,n=0; //自动变量m,n m=m+1; n=n+x+y; cout<<"m="<<m<<'\t'<<"n="<<n<<endl; } } 程序运行结果为: m=1 n=15 m=1 n=15
相关文档
最新文档