第18讲 局部变量 全局变量和存储分类 局部变量作用域和生存期
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第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]); } }
…….
动 态 存 储 区
auto变量的应用示例(4/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
内存
main: a main: b main: t
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
20 10 10
…….
动 态 存 储 区
auto变量的应用示例(7/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
main: a main: b f: x f: y f: t
主函数运行结束时,内存中 所有的变量均被释放
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
10 20 20 10 30
…….
动 态 存 储 区
2. register变量
寄存器变量也是自动类变量.这种变量的值是保留在CPU内 部的寄存器中. 特点:程序运行速度快.主要针对过去的计算机速度慢. 运算速度慢,访问内存速度慢 说明 1.一个计算机系统中的寄存器数目是有限的,因此只能定义少 量的寄存器变量.当程序中的寄存器变量较多时,或编译程 序认为指定的变量不适合放在寄存器中时,将自动按auto变 量来处理.因此,register说明只是对编译程序的一种建议. 2.由于register变量的值是放在寄存器内而不是放在内存中, 因此register变量没有地址,也就不能对它进行求地址运算. 3.为了提高寄存器的利用率,register变量应尽量做到即定义 即使用,用完就释放. 4.有些编译程序不理采寄存器变量的定义,直接将其当auto变 量来处理.
内存
main: a main: b f: x f: y f: t
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
10 20 10 20 30
…….
动 态 存 储 区
auto变量的应用示例(5/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
10 20 main: t
…….
动 态 存 储 区
auto变量的应用示例(6/8)
main() {void f(int x,int; if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
10 20 f: x f: y f: t
…….
动 态 存 储 区
auto变量的应用示例(8/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30 x=20,y=10,x+y=30 内存
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); }
内存
2000 2001 2002 2003 2004 2005 2006 2007
main:a main: b
动 态 存 储 区
…….
auto变量的应用示例(2/8)
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
auto变量的应用示例(1/8)
main() main() {void f(int x,int y); {void f(int x,int y); int aa,,b; int b; a=10;b=20; a=10;b=20; f(a,b); f(a,b); if(a<b) if(a<b) {int t; {int t; t=a; a=b;b=t; t=a; a=b;b=t; } } f(a,b); f(a,b); } }
6. 变量的存储类型,作用域与生存期
局部变量 存储类别 存储方式 auto register 动态 static局部 全部变量 static外部 静态 静态存储区 外部
寄存器 存储区 动态区 生存期 函数调用开始至结束
程序整个运行期间
作用域 定义变量的函数或复合语句内 本文件 其它文件 赋初值 每次函数调用时 编译时赋初值,只赋一次 未赋初值 不确定 自动赋初值0或空字符 局部变量默认为auto型 register型变量个数受限,且不能为long, double, float型 static局部变量具有全局寿命和局部可见性 static局部变量具有可继承性 extern不是变量定义,可扩展外部变量作用域
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
3. 全局变量
定义:在函数外定义,可为本文件内的所有函数共用 有效范围:从定义变量的位置开始到本源文件结束,及有 extern说明的其它源文件
全局变量说明 全局变量说明: extern 说明
数据类型
变量表;
全局变量定义 次数: 只能1次 位置: 所有函数之外 分配内存: 分配内存,可初始化
全局变量说明 可说明多次 函数内或函数外 不分配内存,不可初始化
8.2 局部变量及其作用域和生存期
1. auto变量 在函数内部(或复合语句内)定义变量时,若使用auto(或缺 省) ,称为"动态局部变量" 内. 如在一函数中有定义:auto int a; 或 int auto a; 或 int a; 则整型变量a是一个自动类的局部变量. auto变量的特点: 1. 由于自动类局部变量的存储单元是在进入这些局部变量所 在的函数体(或复合语句)时分配,退出所在的函数体(或复 合语句)时释放,所以这些变量的生存期是"短期" . 2. 多次进入同一函数体(或复合语句)时,自动类局部变量所 分配的存储位置可能不同.所以,未赋初值的自动变量其 值为一个随机值. 3.不同函数中使用同名变量不会相互影响.
若全局变量与局部变量同名,则全局变量被屏蔽 应尽量少使用全局变量,因为: 全局变量在程序全部执行过程中始终占用存储单元 降低了函数的通用性,可靠性,可移植性 降低程序清晰性,容易出错
4. 变量的存储属性 变量的属性
数据类型:变量所持有的数据的性质(操作属性) 存储属性
存储器类型:寄存器,静态存储区,动态存储区 生存期:变量在某一时刻存在-------静态变量与动态变量 作用域:变量在某区域内有效-------局部变量与全局变量
指定变量的存储类型时所要用的关键字
auto -----自动型 register-----寄存器型 static ------静态型 extern -----外部型 如: int sum; auto int a,b,c; register int i; static float x,y;
变量定义格式: [存储类型] 数据类型 变量表;
5. 变量的存储类型
静态存储:程序运行期间分配固定存储空间 动态存储:程序运行期间根据需要动态分配存储空间 内存用户区 程序区 静态存储区 动态存储区 全局变量,静态局部变量 形参变量 动态局部变量(auto,register) 函数调用现场保护和返回地址等
生存期 静态变量:从程序开始执行到程序结束 动态变量:从包含该变量定义的函数开始执行至函数执行结束
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007
10 20
动 态 存 储 区
…….
auto变量的应用示例(3/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); }
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
10 20 f: x f: y f: t
局部变量 全局变量和存储分类 局部变量及其作用域和生存期
第八章 用户标识符的作用域和存储类
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]); } }
…….
动 态 存 储 区
auto变量的应用示例(4/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
内存
main: a main: b main: t
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
20 10 10
…….
动 态 存 储 区
auto变量的应用示例(7/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
main: a main: b f: x f: y f: t
主函数运行结束时,内存中 所有的变量均被释放
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
10 20 20 10 30
…….
动 态 存 储 区
2. register变量
寄存器变量也是自动类变量.这种变量的值是保留在CPU内 部的寄存器中. 特点:程序运行速度快.主要针对过去的计算机速度慢. 运算速度慢,访问内存速度慢 说明 1.一个计算机系统中的寄存器数目是有限的,因此只能定义少 量的寄存器变量.当程序中的寄存器变量较多时,或编译程 序认为指定的变量不适合放在寄存器中时,将自动按auto变 量来处理.因此,register说明只是对编译程序的一种建议. 2.由于register变量的值是放在寄存器内而不是放在内存中, 因此register变量没有地址,也就不能对它进行求地址运算. 3.为了提高寄存器的利用率,register变量应尽量做到即定义 即使用,用完就释放. 4.有些编译程序不理采寄存器变量的定义,直接将其当auto变 量来处理.
内存
main: a main: b f: x f: y f: t
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
10 20 10 20 30
…….
动 态 存 储 区
auto变量的应用示例(5/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
10 20 main: t
…….
动 态 存 储 区
auto变量的应用示例(6/8)
main() {void f(int x,int; if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
10 20 f: x f: y f: t
…….
动 态 存 储 区
auto变量的应用示例(8/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30 x=20,y=10,x+y=30 内存
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); }
内存
2000 2001 2002 2003 2004 2005 2006 2007
main:a main: b
动 态 存 储 区
…….
auto变量的应用示例(2/8)
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
auto变量的应用示例(1/8)
main() main() {void f(int x,int y); {void f(int x,int y); int aa,,b; int b; a=10;b=20; a=10;b=20; f(a,b); f(a,b); if(a<b) if(a<b) {int t; {int t; t=a; a=b;b=t; t=a; a=b;b=t; } } f(a,b); f(a,b); } }
6. 变量的存储类型,作用域与生存期
局部变量 存储类别 存储方式 auto register 动态 static局部 全部变量 static外部 静态 静态存储区 外部
寄存器 存储区 动态区 生存期 函数调用开始至结束
程序整个运行期间
作用域 定义变量的函数或复合语句内 本文件 其它文件 赋初值 每次函数调用时 编译时赋初值,只赋一次 未赋初值 不确定 自动赋初值0或空字符 局部变量默认为auto型 register型变量个数受限,且不能为long, double, float型 static局部变量具有全局寿命和局部可见性 static局部变量具有可继承性 extern不是变量定义,可扩展外部变量作用域
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); } x=10,y=20,x+y=30
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
3. 全局变量
定义:在函数外定义,可为本文件内的所有函数共用 有效范围:从定义变量的位置开始到本源文件结束,及有 extern说明的其它源文件
全局变量说明 全局变量说明: extern 说明
数据类型
变量表;
全局变量定义 次数: 只能1次 位置: 所有函数之外 分配内存: 分配内存,可初始化
全局变量说明 可说明多次 函数内或函数外 不分配内存,不可初始化
8.2 局部变量及其作用域和生存期
1. auto变量 在函数内部(或复合语句内)定义变量时,若使用auto(或缺 省) ,称为"动态局部变量" 内. 如在一函数中有定义:auto int a; 或 int auto a; 或 int a; 则整型变量a是一个自动类的局部变量. auto变量的特点: 1. 由于自动类局部变量的存储单元是在进入这些局部变量所 在的函数体(或复合语句)时分配,退出所在的函数体(或复 合语句)时释放,所以这些变量的生存期是"短期" . 2. 多次进入同一函数体(或复合语句)时,自动类局部变量所 分配的存储位置可能不同.所以,未赋初值的自动变量其 值为一个随机值. 3.不同函数中使用同名变量不会相互影响.
若全局变量与局部变量同名,则全局变量被屏蔽 应尽量少使用全局变量,因为: 全局变量在程序全部执行过程中始终占用存储单元 降低了函数的通用性,可靠性,可移植性 降低程序清晰性,容易出错
4. 变量的存储属性 变量的属性
数据类型:变量所持有的数据的性质(操作属性) 存储属性
存储器类型:寄存器,静态存储区,动态存储区 生存期:变量在某一时刻存在-------静态变量与动态变量 作用域:变量在某区域内有效-------局部变量与全局变量
指定变量的存储类型时所要用的关键字
auto -----自动型 register-----寄存器型 static ------静态型 extern -----外部型 如: int sum; auto int a,b,c; register int i; static float x,y;
变量定义格式: [存储类型] 数据类型 变量表;
5. 变量的存储类型
静态存储:程序运行期间分配固定存储空间 动态存储:程序运行期间根据需要动态分配存储空间 内存用户区 程序区 静态存储区 动态存储区 全局变量,静态局部变量 形参变量 动态局部变量(auto,register) 函数调用现场保护和返回地址等
生存期 静态变量:从程序开始执行到程序结束 动态变量:从包含该变量定义的函数开始执行至函数执行结束
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007
10 20
动 态 存 储 区
…….
auto变量的应用示例(3/8)
main() {void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(a<b) {int t; t=a; a=b;b=t; } f(a,b); }
void f(int x,int y) {int t; t=x+y; printf("x=%d,y=%d,x+y=%d\n",x,y,t); }
内存
main: a main: b
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
10 20 f: x f: y f: t