资源预览内容
第1页 / 共34页
第2页 / 共34页
第3页 / 共34页
第4页 / 共34页
第5页 / 共34页
第6页 / 共34页
第7页 / 共34页
第8页 / 共34页
第9页 / 共34页
第10页 / 共34页
亲,该文档总共34页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第8章 函数与预处理命令华北电力大学华北电力大学 计算机系计算机系C C语言程序设计语言程序设计(2)2005年3月1第8章 函数与预处理命令8.6 变量的存储类别及变量的生存期8.7 编译预处理8.8 多文件程序的调试方法8.9 指向函数的指针变量28.6 变量的存储类别及变量的生存期8.6.1 变量的生存期与变量的存储分类变量的生存期:变量在内存中占据存储空间的时间。思考思考:1. 1. 何时何时为变量分配内存单元为变量分配内存单元?2. 2. 将变量分配在内存的什么将变量分配在内存的什么区域区域?3 3. . 变量占据内存的变量占据内存的时间时间(生存期生存期)?)?程序代码区静态存储区动态存储区存储分配动态存储变 量静态存储变量38.6.2 变量的存储类别变 量 的 属 性数据类型:数据类型:intint x; x; 决定为变量分配内存单元的长度,决定为变量分配内存单元的长度, 数据的存放形式,数据的存放形式, 数的范围。数的范围。存储类别:存储类别:staticstatic intint x; x; 决定了变量的生存期,决定了变量的生存期, 给它分配在哪个存储区。给它分配在哪个存储区。4变量定义语句的一般形式 存储类别存储类别 数据类型数据类型 变量名变量名1, , 1, , 变量名变量名n ;n ;autoauto(自动的)(自动的) registerregister(寄存器的)(寄存器的) staticstatic(静态的)(静态的) externextern(外部的)(外部的)1自动变量(auto类别,可以省略)局部变量可以定义为自动变量。void main() int x,y; void main() auto int x,y; 自动变量自动变量等价可省5 内存分配 调用函数或执行分程序时在动态存储区为其分配存 储单元,函数或分程序执行结束,所占内存空间即 刻释放。 变量的初值 定义变量时若没赋初值,变量的初值不确定;如果 赋初值则每次函数被调用时执行一次赋值操作。 生存期 在函数或分程序执行期间。 作用域 自动变量所在的函数内或分程序内。自动变量自动变量62静态变量(static类别)除形参外,局部变量和全局变量都可以定义为静 态变量。 局部静态变量(或称内部静态变量)局部静态变量(或称内部静态变量)全局静态变量(或称外部静态变量)静态变量静态变量静态变量静态变量static int a; main( ) float x,y; f( ) static int b=1; 全局静态变量局部静态变量局部静态变量自动变量自动变量不 能 省7 内存分配 编译时,将其分配在内存的静态存储区中,程序运 行结束释放该单元。 静态变量的初值 若定义时未赋初值,在编译时,系统自动赋初值为 0;若定义时赋初值,则仅在编译时赋初值一次, 程序运行后不再给变量赋初值 。 生存期 整个程序的执行期间。 作用域 局部静态变量的作用域是它所在的函数或分程序。 全局静态变量的作用域是从定义处开始到本源文件 结束。静态变量静态变量8#include int func(int n)int f=1;f=f*n;return f; void main() int i,n=5; for(i=2;i int func(int n)static int f=1;f=f*n;return f; void main() int i,n=7; for(i=2;i 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声明外部变量定义外部变量148.6.3 归纳变量的分类1按照变量的作用域对变量分类 局部变量 全局变量 2按照变量的生存期对变量分类 静态存储变量 包括:局部静态变量和全局静态变量 动态存储变量 包括:自动变量15源文件源文件 *.*.c c运行文件运行文件 *.*.exeexe编译编译编译编译编译编译目标文件目标文件 *.*.objobj连接连接编译编译连接连接连接连接编译预处理编译预处理 编编 译译编译预处理包括:宏定义文件包含条件编译(不讲)8.7 8.7 编译预处理编译预处理16#define 宏名 字符串宏定义的功能: 在进行编译前,用字符串原样替换程序中的宏名 这个替换过程称为“宏替换”或“宏展开”,字 符串也称为替换文本。 命令的一般格式:命令的一般格式:8.7.1 8.7.1 不带参数的宏定义不带参数的宏定义8.7 编译预处理(续)178.7 编译预处理(续)例如:例如:#define #define PIPI 3.143.14void main()void main() float float r,s,cr,s,c; ;scanf(“%f”,);s = r * r * s = r * r * PIPI; ;c = 2 * r * c = 2 * r * PIPI; ;printf(“sprintf(“s=%f, =%f, c=%c=%f”,s,cf”,s,c);); 替 换3.143.143.143.14编编 译译188.7 编译预处理(续)双引号中有与宏名相同的字符串不进行替换。已经定义的宏名可以被后定义的宏名引用。在预处 理时将层层进行替换。说明说明: : 为了增加程序的可读性,建议宏名用大写字母,为了增加程序的可读性,建议宏名用大写字母, 其他的标识符用小写字母。其他的标识符用小写字母。19【例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“,printf(“S=%.2f V=%.2fn“,S,V); 编译预处理后的程序: void main( ) float r;printf(“nInput r:“);scanf(“%f“,printf(“S=%.2f V=%.2fn“,3.14*r*r, 4* 3.14*r*r *r/3); SVSV进入编译进入编译20命令的一般形式8.7.2 8.7.2 带参数的宏定义带参数的宏定义#define #define 宏名宏名( (形参表形参表) ) 字符串字符串功能:在编译预处理时,把源程序中所有带参数的宏名 用宏定义中的字符串替换,并且用宏名后圆括号中 的实参替换字符串中的形参。例如:#define MAX(X,Y) (X)(Y)?(X):(Y)8.7 编译预处理(续)218.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,bMAX(a,b) ) 替换成字符串 (x)(x)(y)?(x):(yy)?(x):(y) )。 用实参a替换形参x,实参b替换形参y。 程序中的两个printf语句被展开为: printf(“%dn“, (a)(b)?(a):(b); printf(“%dn“, (a+m)(b+n)?( a+m):( b+n);228.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)MA(1+a+b) 用x*(x-1)x*(x-1) 替换。 用1+a+b替换x。 printf语句被展开为: printf(“%dn“, 1+a+b*(1+a+b-1);特别注意: 由于替换文 本中的x没 有用括号括 起,因此, 1+a+b也不 能用括号括 起。程序输出结果:8238.7 编译预处理(续)命令的一般形式 格式1: #include 格式2: #include “文件名“8.7.3 8.7.3 文件包含文件包含文件包含是将指定的某个源文件的内容全部包文件包含是将指定的某个源文件的内容全部包 含到当前文件中。用含到当前文件中。用includeinclude命令实现。命令实现。用 用格式格式1 1,预处理程序仅在系统指定目录下查找指,预处理程序仅在系统指定目录下查找指 定文件。定文件。用 用格式格式2 2,预处理程序首先在,预处理程序首先在当前目录中当前目录中查找指定查找指定 文件,若找不到再到文件,若找不到再到 系统指定目录中查找。系统指定目录中查找。247.8 编译预处理(续)例如:调用sin(x) 函数时,要在程序的开头使用 如下命令: #include 在预处理时,用math.h文件内容替换 #include 命令行。2 2功能功能在预处理时,将 在预处理时,将includeinclude命令后指定文件的内命令后指定文件的内 容替换该命令行。容替换该命令行。258.8 多文件程序的调试方法操作步骤如下: 在VC 环境下先建立一个工程,再在工程中建立若 干个源文件,其中只有一个文件中有主函数main(),例 如:文件内容如下:file1.cfile2.cfile3.c 依次对上述3个文件编译,编译通过之后,再运行 即可1. 1. 使用工程文件将多个文件连接成一个可使用工程文件将多个文件连接成一个可 执行文件的方法执行文件的方法 例如:将例如:将file1.cfile1.c、file2.cfile2.c和和file3.cfile3.c合并成一个可执行文件合并成一个可执行文件。268.8多文件程序的调试方法(续)file3.cfile3.c#include “file2.c“ #include “file3.c“file1.cfile1.cAfile2.cfile2.cBCBCAfile1.cfile1.c预处理前预处理前预处理后预处理后278.9 指向函数的指针变量l前面我们已经学过用指针变量间接访问一般 变量、一维数组元素和二维数组元素lC语言允许用指针变量间接调用函数,使程 序设计更加灵活方便 指向函数的指针变量定义形式: 函数类型 (*指针变量名)(); 如:void (*p)();p=welcome;/函数名是函数的入口地址(*p)();/等价于welcome(); 说明:welcome是一个已经定义好的无返回 值和形参的函数288.9 指向函数的指针变量(续)如:int (*s)(int int);s=max;f=(*s)(5,7
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号