已阅读5页,还剩29页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,第8章 函数与预处理命令,华北电力大学 计算机系,C 语言程序设计,(2),2,第8章 函数与预处理命令,8.6 变量的存储类别及变量的生存期 8.7 编译预处理 8.8 多文件程序的调试方法 8.9 指向函数的指针变量,3,8.6 变量的存储类别及变量的生存期,8.6.1 变量的生存期与变量的存储分类,变量的生存期:变量在内存中占据存储空间的时间。,思考:1. 何时为变量分配内存单元? 2. 将变量分配在内存的什么区域? 3. 变量占据内存的时间(生存期)?,动态存储变量,静态存储变量,4,8.6.2 变量的存储类别,变量的属性,数据类型:int x; 决定为变量分配内存单元的长度, 数据的存放形式, 数的范围。,存储类别:static int x; 决定了变量的生存期, 给它分配在哪个存储区。,5,变量定义语句的一般形式,存储类别 数据类型 变量名1, , 变量名n ;,auto(自动的) register(寄存器的)static(静态的) extern(外部的),1自动变量(auto类别,可以省略) 局部变量可以定义为自动变量。,6, 内存分配 调用函数或执行分程序时在动态存储区为其分配存储单元,函数或分程序执行结束,所占内存空间即刻释放。 变量的初值 定义变量时若没赋初值,变量的初值不确定;如果赋初值则每次函数被调用时执行一次赋值操作。 生存期 在函数或分程序执行期间。 作用域 自动变量所在的函数内或分程序内。,自动变量,7,2静态变量(static类别),除形参外,局部变量和全局变量都可以定义为静态变量。,8, 内存分配 编译时,将其分配在内存的静态存储区中,程序运行结束释放该单元。 静态变量的初值 若定义时未赋初值,在编译时,系统自动赋初值为0;若定义时赋初值,则仅在编译时赋初值一次,程序运行后不再给变量赋初值 。 生存期 整个程序的执行期间。 作用域 局部静态变量的作用域是它所在的函数或分程序。全局静态变量的作用域是从定义处开始到本源文件结束。,静态变量,9,#include int func(int n) int f=1; f=f*n; return f; void main() int i,n=5; for(i=2;i=n;i+) printf(“%d,”,func(i); ,#include int func(int n) static int f=1; f=f*n; return f; void main() int i,n=7; for(i=2;i=n;i+) printf(“%d,”,func(i); ,运行结果: 2,3,4,5,6,7,运行结果: 2,6,24,120,720,5040,,10,int c; static int a; main( ) float x,y; char s; f( ) static int b=1; ,3.外部变量(extern类别),在函数外定义的变量若没有用 static说明,则是外部变量。外部变量只能隐式定义为extern类别,不能显式定义。,11, 内存分配 编译时,将其分配在静态存储区,程序运行结束释放该单元。 变量的初值 若定义变量时未赋初值,在编译时,系统自动赋初值为0。 生存期 整个程序的执行期间。 作用域 从定义处开始到本源文件结束。 此外,还可以用extern进行声明,以使其作用域扩大到该程序的其它文件中。,外部变量,问题:全局静态变量的作用域可以扩展到本程序的其它文件吗?,12,外部变量声明的一般格式,extern 数据类型 变量名1,变量名n; 或 extern 变量名1,变量名n;,注意: 外部变量声明用关键字extern,而外部变量的定义不能用extern,只能隐式定义。 定义外部变量时,系统要给变量分配存储空间,而对外部变量声明时,系统不分配存储空间,只是让编译系统知道该变量是一个已经定义过的外部变量,与函数声明的作用类似。,13,int p=1,q=5; float f1(int a) extern char c1,c2; char c1,c2; char f2(int x,int y) main( ) ,思考:在f1函数中声明c1、c2的作用是什么?如何修改程序使所有函数都可以使用外部变量而又不需要声明?,【例8.24】在一个文件内声明外部变量。,14,【例8.25】在多文件的程序中声明外部变量。,file1.c文件中程序如下: #include int i; void main( ) void f1( ),f2( ),f3( ); i=1; f1( ); printf(“tmain: i=%d“,i); f2( ); printf(“tmain: i=%d“,i); f3( ); printf(“tmain: i=%dn“,i); void f1( ) i+; printf(“nf1: i=%d“,i); ,file2.c文件中程序如下: #include extern int i; void f2( ) int i=3; printf(“nf2: i=%d“,i); void f3( ) i=3; printf(“nf3: i=%d“,i); ,程序输出结果: f1: i=2 main: i=2 f2: i=3 main: i=2 f3: i=3 main: i=3,声明外部变量,定义外部变量,15,8.6.3 归纳变量的分类,1按照变量的作用域对变量分类 局部变量 全局变量 2按照变量的生存期对变量分类 静态存储变量 包括:局部静态变量和全局静态变量 动态存储变量 包括:自动变量,16,源文件 *.c,运行文件 *.exe,编译,编译,编译,目标文件 *.obj,连接,编译,连接,连接,编译预处理包括: 宏定义 文件包含 条件编译(不讲),8.7 编译预处理,17,#define 宏名 字符串,宏定义的功能: 在进行编译前,用字符串原样替换程序中的宏名 这个替换过程称为“宏替换”或“宏展开”,字符串也称为替换文本。,命令的一般格式:,8.7.1 不带参数的宏定义,8.7 编译预处理(续),18,8.7 编译预处理(续),例如:,#define PI 3.14 void main() float r,s,c; scanf(“%f”, ,替 换,3.14,3.14,编 译,19,8.7 编译预处理(续),双引号中有与宏名相同的字符串不进行替换。 已经定义的宏名可以被后定义的宏名引用。在预处理时将层层进行替换。,说明: 为了增加程序的可读性,建议宏名用大写字母,其他的标识符用小写字母。,20,【例7.29】不带参数的宏定义。,源程序: #define PI 3.14 #define S PI*r*r #define V 4*S*r/3 void main( ) float r; printf(“nInput r:“); scanf(“%f“, ,编译预处理后的程序: void main( ) float r; printf(“nInput r:“); scanf(“%f“, ,S,V,S,V,21,命令的一般形式,8.7.2 带参数的宏定义,#define 宏名(形参表) 字符串,功能: 在编译预处理时,把源程序中所有带参数的宏名用宏定义中的字符串替换,并且用宏名后圆括号中的实参替换字符串中的形参。,例如:#define MAX(X,Y) (X)(Y)?(X):(Y),8.7 编译预处理(续),22,8.7 编译预处理(续),【例8.30】带参数的宏定义。 #define MAX(x,y) (x)(y)?(x):(y) void main( ) printf(“%dn“,a,b, MAX(a,b); printf(“%dn“,MAX(a+m,b+n); ,分两次替换: 将宏名MAX(a,b) 替换成字符串 (x)(y)?(x):(y)。 用实参a替换形参x,实参b替换形参y。 程序中的两个printf语句被展开为: printf(“%dn“, (a)(b)?(a):(b); printf(“%dn“, (a+m)(b+n)?( a+m):( b+n);,23,8.7 编译预处理(续),【例8.31】分析下面程序运行后的输出结果。 #define MA(x) x*(x-1) void main( ) int a=1,b=2; printf(“%dn“, MA(1+a+b); ,分两次替换: MA(1+a+b) 用x*(x-1) 替换。 用1+a+b替换x。 printf语句被展开为: printf(“%dn“, 1+a+b*(1+a+b-1);,特别注意: 由于替换文本中的x没有用括号括起,因此,1+a+b也不能用括号括起。,程序输出结果:8,24,8.7 编译预处理(续),命令的一般形式 格式1: #include 格式2: #include “文件名“,8.7.3 文件包含,文件包含是将指定的某个源文件的内容全部包含到当前文件中。用include命令实现。,用格式1,预处理程序仅在系统指定目录下查找指定文件。 用格式2,预处理程序首先在当前目录中查找指定文件,若找不到再到系统指定目录中查找。,25,7.8 编译预处理(续),例如:调用sin(x) 函数时,要在程序的开头使用如下命令: #include 在预处理时,用math.h文件内容替换 #include 命令行。,2功能 在预处理时,将include命令后指定文件的内容替换该命令行。,26,8.8 多文件程序的调试方法,操作步骤如下: 在VC 环境下先建立一个工程,再在工程中建立若干个源文件,其中只有一个文件中有主函数main(),例如:文件内容如下: file1.c file2.c file3.c 依次对上述3个文件编译,编译通过之后,再运行即可,1. 使用工程文件将多个文件连接成一个可执行文件的方法,例如:将file1.c、file2.c和file3.c合并成一个可执行文件。,27,8.8多文件程序的调试方法(续),file3.c,#include “file2.c“ #include “file3.c“,file1.c,A,file2.c,B,C,B,C,A,file1.c,预处理前,预处理后,28,8.9 指向函数的指针变量,前面我们已经学过用指针变量间接访问一般变量、一维数组元素和二维数组元素 C语言允许用指针变量间接调用函数,使程序设计更加灵活方便 指向函数的指针变量定义形式: 函数类型 (*指针变量名)(); 如:void (*p)(); p=welcome;/函数名是函数的入口地址 (*p)();/等价于welcome(); 说明:welcome是一个已经定义好的无返回值和形参的函数,29,8.9 指向函数的指针变量(续),如:int (*s)(int int); s=max; f=(*s)(5,7);/等价于f=max(5,7); 说明:max是一个已经定义好的返回值为整型和有两个int型参数的函数,用指针变量调用函数的形式: (*指针变量名)(实参表),30,注意以下定义的都是什么指针变量 int *p,*q5, (*f)(float *,int ); p: 指针变量,可以存放一个整型变量的地址 q: 指针数组,有5个可以存放整型变量地址的指针变量 f: 指针变量,可以存放函数值是int,带有两个参数,一个是float的指针类型,另一个是int类型的函数的入口地址,31,Test.cpp,#include int func(int n) static int f=1; f=f*n; return f; void main() int i,n=7; int (*p)(int); p=func; for(i=2;i=n;i+) printf(“%d,“,(*p)(i); ,32,Test.c,#include int func(int n) static int f=1; f=f*n; return f; void main() int i,n=7; int (*p)( ); p=func; for(i=2;i=n;i+) printf(“%d,“,(*p)(i); ,33,用指针变量调用函数,先定义指针变量 让指针变量指向函数 指针变量=函数名 用指针变量调用函数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 4662-2025滚动轴承额定静载荷
- 2025年透明包装材料研发项目可行性研究报告及总结分析
- 2024年重庆市从村(社区)干部中录用公务员考试真题
- 薄板CMT焊接工艺研究
- 2025年企业系统集成服务合同协议
- 2025年线上虚拟现实平台开发可行性研究报告及总结分析
- 2020-2025年中级注册安全工程师之安全生产技术基础题库综合试卷A卷附答案
- 2025年湖南省永州市蓝山县保安员招聘考试题库附答案解析
- 2025年虚拟社交平台的发展项目可行性研究报告及总结分析
- 2025年高端制造业市场扩展可行性研究报告及总结分析
- 静脉用药集中调配培训
- 2025及未来5-10年高速插秧机项目投资价值市场数据分析报告
- 护患沟通培训课件
- 安全管理人员培训课件
- 企业财务制度规范范本合集
- 注塑件外观不良
- 2026年中国飞机MRO软件项目经营分析报告
- 2025危大钢结构全流程施工危险源辨识、施工技术及监管要点指南(符合31号文)
- 特种设备安全管理组织机构
- 河道生态修复与水质改善方案
- 人工智能通识教程 课件 第12章-提示词工程
评论
0/150
提交评论