收藏 分享(赏)

《C语言程序设计教程》课件--第7章.ppt

上传人:dreamzhangning 文档编号:3349697 上传时间:2018-10-16 格式:PPT 页数:76 大小:592KB
下载 相关 举报
《C语言程序设计教程》课件--第7章.ppt_第1页
第1页 / 共76页
《C语言程序设计教程》课件--第7章.ppt_第2页
第2页 / 共76页
《C语言程序设计教程》课件--第7章.ppt_第3页
第3页 / 共76页
《C语言程序设计教程》课件--第7章.ppt_第4页
第4页 / 共76页
《C语言程序设计教程》课件--第7章.ppt_第5页
第5页 / 共76页
点击查看更多>>
资源描述

1、1,第7章 函数与预处理命令,北京科技大学 计算机系,C 语言程序设计,2005年3月,2,第7章 函数与预处理命令,7.1 概述 7.2 函数的定义与调用 7.3 数组作函数参数 7.4 函数的嵌套调用和递归调用 7.5 局部变量和全局变量及其作用域 7.6 变量的存储类别及变量的生存期 7.7 函数的存储分类 7.8 编译预处理 7.9 多文件程序的调试方法,2005年3月,3,7.1 概述, 程序结构清晰,可读性好。 减少重复编码的工作量。 可多人共同编制一个大程序,缩短程序设计周期,提高程序设计和调试的效率。,使用函数的 好处,2005年3月,4,【例7.1】求一个整数的立方。,int

2、 cube (int x) /* 函数定义 */ return (x * x * x); main( ) int f, a;printf(“nEnter an integer number:“);scanf(“%d“, ,程序运行情况如下: Enter an integer number:2 2 * 2 * 2 = 8,函数调用,程序的执行总是 从main函数开始,2005年3月,5, 一个C源程序可以由一个或多个源程序文件组成。C编译系统在对C源程序进行编译时是以文件为单位进行的。 一个C源程序文件可以由一个或多个函数组成。所有函数都是独立的。主函数可以调用其它函数,其它函数可以相互调用。

3、在一个C程序中,有且仅有一个主函数main。C程序的执行总是从main函数开始,调用其它函数后最终回到main函数,在main函数中结束整个程序的运行。,说明,2005年3月,6, 函数的种类,从函数定义形式分: 有参函数: 在主调(用)函数和被调(用)函数之间通过参数进行数据传递, 如:int cube (int x) 无参函数: 如:getchar( ) 在调用无参函数时,主调函数不需要将数据传递给无参函数。,从使用的角度看: 标准函数(库函数) 库函数是由系统提供的。如:getchar( )、sin(x)等。在程序中可以直接调用它们。附录A列出了C的部分库函数。 用户自定义函数。 如:例

4、7.1中的cube函数。,2005年3月,7,【例7.2】无参函数的定义与调用。,void welcome ( ) printf(“*n“); printf(“ Welcome to China n“);printf(“*n“); main( ) welcome( );,程序的输出结果如下: * Welcome to China *,2005年3月,8,7.2.1 函数的定义,函数定义的一般形式,函数类型 函数名(类型名 形式参数1, ) 说明语句执行语句 ,例如:求两个数的最大值。 int max(int x,int y) int z;z = x y ? x : y;return( z );

5、 ,类型省略时默认为int类型,2005年3月,9,int max(x,y) int x,y; int z;z = x y ? x : y;return( z ); ,int max(x,y) int x,y; 或 int max(int x,y) ,或 int max(x,y) int x,y,z; z = x y ? x : y;return( z ); ,花括号中也可以为空,这种函数叫空函数 。 不能在函数体内定义其他函数,即函数不能嵌套定义。,形参也可以这样定义,2005年3月,10,函数名(实参表列),在C语言中,把函数调用也作为一个表达式。因此凡是表达式可以出现的地方都可以出现函数

6、调用。例如: welcome( ); if (iabs (a)max) max=iabs(a); m=max(c,max(a,b);,7.2.2 函数的调用,函数调用的一般形式:,2005年3月,11,int sum100( ) int i,t=0;for (i=1; i=100; i+)t+=i;return (t); main( ) int s;s=sum100( );printf(“%dn“, s); ,程序输出结果: 5050,int sum ( int x ) int i,t=0;for (i=1; i=x; i+)t+=i;return (t); main( ) int s;s=s

7、um (100);printf(“%dn“, s); ,【例7.3】求1100的累加和。,思考:两个程序有何不同,程序输出结果: 5050,?,2005年3月,12,void swap(int x, int y) int z;z=x; x=y; y=z; printf(“nx=%d,y=%d“,x ,y); main( ) int a= 10,b=20;swap(a,b); printf(“na=%d,b=%dn“,a,b); ,7.2.3 函数参数与函数的返回值,1函数的形式参数与实际参数,程序输出结果: x=20,y=10 a=10,b=20,形式参数(形参),实际参数(实参),【例7.4

8、】编一程序,将主函数中的两个变量的值传递给swap函数中的两个形参,交换两个形参的值。,单向值传递,2005年3月,13,有关形参和实参的说明:, 当函数被调用时才给形参分配内存单元。调用结束,所占内存被释放。 实参可以是常量、变量或表达式,但要求它们有确定的值。 实参与形参类型要一致,字符型与整型可以兼容。 实参与形参的个数必须相等。在函数调用时,实参的值赋给与之相对应的形参。“单向值传递”。,注意:在TC中,实参的求值顺序是从右到左。,2005年3月,14,【例7.5】函数调用中实参的求值顺序。,void fun(int a,int b) printf(“a=%d,b=%dn“,a,b);

9、 main( ) int m=5;fun(3+m, m+); ,程序输出结果: a=9,b=5,2005年3月,15,2.函数的类型与函数的返回值,说明: 函数的类型决定了函数返回值的类型。若省略函数的类型,系统默认其为int型。 无返回值的函数应将其类型定义为void (空)类型。, 函数的类型,【例7.6】输出两个数中的大数。,max(int x,int y) int z;z=xy?x:y;return (z); /* 返回z的值 */ main( ) int a,b,c;scanf(“%d,%d“, ,2005年3月,16,函数的返回值是通过return语句带回到主调函数的,功能:终止函

10、数的运行,返回主调函数,若有返回值,将返回值带回主调函数。,说明: 若函数没有返回值,return语句可以省略。 return语句中的表达式类型一般应和函数的类型一致,如果不一致,系统自动将表达式类型转换为函数类型。, 函数的返回值,return 语句格式:,return (表达式); 或 return 表达式 ; 或 return;,2005年3月,17,【例7.8】计算并输出圆的面积。,s(int r) return 3.14*r*r; main( ) int r,area;scanf(“%d“, ,自动转换为int型,思考: 若要得到单精度实型的圆面积,程序应如何修改,程序运行情况如下:

11、 2 12,?,2005年3月,18,7.2.4 对被调函数的声明和函数原型,变量要先定义后使用,函数也如此。即被调函数的定义要出现在主调函数的定义之前。如swap函数: 允许整型函数(且参数也是整型)的定义出现在主调函数之后。如max函数: 如果非整型函数在主调函数之后定义,则应在主调函数中或主调函数之前对被调函数进行声明。,void swap(int x, int y) main( ) swap(a,b); ,main( ) c=max(a,b); max(int x,int y) ,2005年3月,19,对被调函数进行声明的一般形式,函数类型 函数名(参数类型1 参数名1,); 或 函数

12、类型 函数名(参数类型1,参数类型2,);,思考: 以下哪种情况需要在主调函数中对被调函数声明 被调函数定义在前,主调函数定义在后。 主调函数定义在前,被调函数定义在后,且被调函数的类型不是整型的。 被调函数定义在后,但被调函数的类型是整型。,第二种形式省略了参数名,此种形式也称为函数的原型。,?,2005年3月,20,main( ) void calc(float x,float y,char opr); float a,b; char opr;printf(“nInput expression:“);scanf(“%f%c%f“, ,对被调函数的声明,【例7.9】计算并输出两个数的和、差、

13、积、商。,2005年3月,21,图 7.2 验证哥德巴赫猜想,【例7.10】 哥德巴赫猜想之一是任何一个大于5的偶数都可以表示为两个素数之和。验证这一论断。,2005年3月,22,#include “math.h“ int prime(int n); main( ) int a,b,c,n;scanf(“%d“, ,/* 穷举法判断素数 */ int prime(int n) int i;for (i=2; i=sqrt(n); i+)if (n%i=0) return 0;return 1; ,可以在main函数的前面对prime函数进行声明。实际上,该声明可以省略,为什么?,程序如下:,2

14、005年3月,23,7.3 数组作函数参数,7.3.1 一维数组元素作函数参数,main( ) int a5,i,m ; for (i=0; i5; i+)scanf(“%d“, ,【例7.11】求5个数中的最小值。,int min(int x, int y) return (xy?x:y); ,用打擂台方法求最小值。m相当于擂主,2005年3月,24,7.3.2 一维数组名作函数参数,数组名表示数组在内存中的起始地址。 例如:数组a在内存中从2000地址开始存放,则a的值为2000。2000是地址值,是指针类型的数据(第8中将介绍指针类型),不能把它看成是整型或其他类型数据。 实参是数组名,

15、形参也应定义为数组形式,形参数组的长度可以省略,但 不能省,否则就不是数组形式了。【例7.12】用冒泡法将10个整数排序。,2005年3月,25,void sort(int b ,int n); void printarr(int b ); main( ) int a10 = 11,22,63,97,58,80,45, 32,73,36;printf(“Before sort:n“);printarr(a);sort(a,10); printf(“After sort:n“);printarr(a); ,void printarr(int b10) int i;for (i=0; i10; i

16、+)printf(“%5d“,bi);printf(“n“);,void sort(int b , int n) int i,j,t;for (i=1; ibj+1) t=bj;bj=bj+1;bj+1=t; ,2005年3月,26,图7.3 调用sort函数,2000,b,形参 b 实际是一个 可以存放地址的变量,a:2000,实参赋给形参,2005年3月,27,#include “stdio.h“ main( ) void scat(char str1 ,char str2 ); char s150,s250; int i,k;printf(“Input s1:“);gets(s1);pr

17、intf(“Input s2:“);gets(s2);scat(s1,s2);printf(“Output s1:%sn“,s1);printf(“Output s2:%sn“,s2); ,void scat(char str1 ,char str2 ) int i=0,k=0;while (str1i!=0) i+;while (str2k!=0) str1i=str2k;i+; k+;str1i=0; ,scat函数还可简化为: void scat(char str1 ,char str2 ) int i=0,k=0;while (str1i) i+;while (str1i+=str2k

18、+); ,【例7.13】编程序,实现字符串连接。,2005年3月,28,以二维数组为例。二维数组名作实参时,对应的形参也应该定义为一个二维数组形式。对形参数组定义时可以指定每一维的大小,也可以省略第一维的大小说明。 【例7.14】编程序,将矩阵转置。设转置前为a矩阵,转置后为b矩阵,如下所示:,思路:将a00b00,a01 b10,a02b20, a10b01,aijbji,。,7.3.3 多维数组作函数参数,2005年3月,29,void turn( ); main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12;int i,j,b43;turn(a,b); pr

19、intf(“array b:n“);for (i=0; i4; i+) for (j=0; j3; j+)printf(“%5d“,bij);printf(“n“); ,/* 矩阵转置函数 */ void turn(int arra 4,int arrb 3) int r, c;for (r=0; r3;r+)for (c=0; c4; c+)arrbcr=arrarc; ,2005年3月,30,7.4 函数的嵌套调用和递归调用,main函数 调用函数 A; ,函数 A 调用函数 B; ,函数 B ,7.4.1 函数的嵌套调用,2005年3月,31,【例7.15】函数的嵌套调用,main( )

20、 int n=3;printf (“%dn“,sub1(n);,sub1(int n) int i,a=0;for (i=n; i0; i-) a+=sub2(i);return a ;,sub2(int n) return n+1; ,程序输出结果: 9,2005年3月,32,7.4.2 函数的递归调用,1递归的基本概念,递归调用:一个函数直接或间接地调用了它本身,就称为函数的递归调用。 递归函数:在函数体内调用该函数本身。,int sub(int x) int y,z;if( ) z=sub(y);else return ; ,例如:,直接调用sub 函数本身,2005年3月,33,2递归

21、函数的执行过程,【例7.16】编一递归函数求n!。,思路:以求4的阶乘为例: 4!=4*3!,3!=3*2!,2!=2*1!,1!=1,0!=1。 递归结束条件:当n=1或n=0时,n!=1。 递归公式:,2005年3月,34,程序如下:,float fact (int n) float f=0;if(n0) printf(“n0,error!“);else if (n=0 | n=1) f=1;else f=fact(n-1)*n;return (f); ,main( ) int n; float y;printf(“nInput n:“);scanf(“%d“, ,运行情况如下: Inpu

22、t a integer number:4 4!=24,2005年3月,35,递归调用过程,2005年3月,36,3编制递归函数的方法, 数值型问题递归函数的编程方法 对于数值型问题,首先要找出解题的数学公式,这个公式必须是递归定义的,且所处理的对象要有规律地递增或递减,然后确定递归结束条件。 【例7.17】编一递归函数求xn 。 思路:首先把xn转化成递归定义的公式,再找出递归结束条件:当n=0时,xn=1。,2005年3月,37,程序如下:,long xn(int x,int n) long f=0;if (n0) printf(“n0,data error!n“);else if (n=0

23、) f=1;else f=x*xn(x,n-1);return (f); main( ) int n,x; long y;scanf(“%d,%d“, ,程序运行情况如下: 2,10 1024,2005年3月,38, 非数值型问题递归函数的编程方法,有些问题不能直接用数学公式求解。非数值型问题比数值型问题更难找出递归的算法。它不能用一个递归公式表示。解决这类问题首先要把问题将大化小,将繁化简。将一个复杂的问题化解成若干个相对简单的小问题,而某个小问题的解法与原问题解法相同,并且越来越简单直至有确定的解。,【例7.18】编制一递归函数,将一个十进制正整数(如:15613)转换成八进制数形式输出。

24、,2005年3月,39,思路:十进制整数转换成八进制整数的方法是除8逆向取余。如图7.5所示。, 非数值型问题递归函数的编程方法(续),2005年3月,40,该题实际上是要把一个十进制数除以8得到的余数逆向输出。就是先得到的余数后输出,最后得到的余数最先输出。 我们先由大化小:求八进制数变成求一系列余数的问题。求第一个余数是将15613除以8取余,因为先得到的余数后输出,所以把这个余数存在一个变量m中,接下去求下一个余数。和求第一个余数的方法相同,只是被除数变成了15613除以8的整数商1951。因此,这是一个递归调用的问题。定义变量m存放余数,x存放被除数。递归算法描述如下:, 非数值型问题

25、递归函数的编程方法(续),2005年3月,41, 先求出余数m:m=x%8; 求x除以8取余后的整数商:x=x/8; 如果x不等于0,递归调用该函数,否则执行。 输出余数m。 返回调用点。, 非数值型问题递归函数的编程方法(续),2005年3月,42,程序如下:,#include “stdio.h“ void dtoo(int x) int m;m=x%8;x=x/8;if (x!=0) dtoo(x);printf(“%d“,m); main( ) int n;scanf(“%d“, ,程序运行情况如下: 15613 15613=(36375)8,2005年3月,43,7.5 局部变量和全局

26、变量及其作用域,7.5.1 变量的作用域,7.5.2 局部变量及其作用域,变量的作用域:变量在程序中可以被使用的范围。 根据变量的作用域可以将变量分为局部变量和全局变量。,局部变量(内部变量):在函数内或复合语句内定义的变量以及形参。 作用域:函数内或复合语句内。,【例7.19】分析下面程序的运行结果及变量的作用域。,问题:一个变量在程序的哪个函数中都能使用吗?,2005年3月,44,void sub(int a,int b) int c; a=a+b; b=b+a; c=b-a; printf(“sub:ta=%d b= %d c= %dn“,a,b,c); ,main( ) int a=1

27、,b=1,c=1; printf(“main:ta=%d b= %d c= %dn“,a,b,c);sub(a,b);printf(“main:ta=%d b= %d c= %dn“,a,b,c); int a=2,b=2;printf(“comp:ta=%d b= %d c= %dn“,a,b,c); printf(“main:ta=%d b= %d c= %dn“,a,b,c); ,“分程序”或“程序块”,程序输出结果: main: a=1 b= 1 c= 1 sub: a=2 b= 3 c= 1 main: a=1 b= 1 c= 1 comp: a=2 b= 2 c= 1 main:

28、a=1 b= 1 c= 1,2005年3月,45,7.5.3 全局变量及其作用域,全局变量(外部变量):在函数外部定义的变量。 作用域:从定义变量的位置开始到本源文件结束。如在其作用域内的函数或分程序中定义了同名局部变量,则在局部变量的作用域内,同名全局变量暂时不起作用。,【例7.20】全局变量和局部变量的作用域。,2005年3月,46,int a = 5; void f(int x, int y) int b,c; b=a+x; c=a-y; printf(“%dt%dt%dn“,a,b,c); ,程序输出结果: 5 11 -2 5 6 7 9 8 7 9 8 10 9 8 10 5 6 1

29、0,全局变量,2005年3月,47,7.6 变量的存储类别及变量的生存期,7.6.1 变量的生存期与变量的存储分类,变量的生存期:变量在内存中占据存储空间的时间。,思考:1. 何时为变量分配内存单元?2. 将变量分配在内存的什么区域?3. 变量占据内存的时间(生存期)?,动态存储变量,静态存储变量,2005年3月,48,7.6.2 变量的存储类别,变量的属性,数据类型: 决定为变量分配内存单元的长度, 数据的存放形式, 数的范围。,存储类别: 决定了变量的生存期, 给它分配在哪个存储区。,2005年3月,49,变量定义语句的一般形式,存储类别 数据类型 变量名1, , 变量名n ;,auto(

30、自动的) register(寄存器的)static(静态的) extern(外部的),1自动变量(auto类别)局部变量可以定义为自动变量。,2005年3月,50, 内存分配 调用函数或执行分程序时在动态存储区为其分配存储单元,函数或分程序执行结束,所占内存空间即刻释放。 变量的初值 定义变量时若没赋初值,变量的初值不确定;如果赋初值则每次函数被调用时执行一次赋值操作。 生存期 在函数或分程序执行期间。 作用域 自动变量所在的函数内或分程序内。,自动变量,2005年3月,51,2静态变量(static类别),除形参外,局部变量和全局变量都可以定义为静态变量。,2005年3月,52, 内存分配

31、编译时,将其分配在内存的静态存储区中,程序运行结束释放该单元。 静态变量的初值 若定义时未赋初值,在编译时,系统自动赋初值为0;若定义时赋初值,则仅在编译时赋初值一次,程序运行后不再给变量赋初值 。 生存期 整个程序的执行期间。 作用域 局部静态变量的作用域是它所在的函数或分程序。全局静态变量的作用域是从定义处开始到本源文件结束。,静态变量,2005年3月,53,int c; static int a; main( ) float x,y; char s; f( ) static int b=1; ,3.外部变量(extern类别),在函数外定义的变量若没有用 static说明,则是外部变量。

32、外部变量只能隐式定义为extern类别,不能显式定义。,2005年3月,54, 内存分配 编译时,将其分配在静态存储区,程序运行结束释放该单元。 变量的初值 若定义变量时未赋初值,在编译时,系统自动赋初值为0。 生存期 整个程序的执行期间。 作用域 从定义处开始到本源文件结束。 此外,还可以用extern进行声明,以使其作用域扩大到该程序的其它文件中。,外部变量,问题:全局静态变量的作用域可以扩展到本程序的其它文件吗?,2005年3月,55,外部变量声明的一般格式,extern 数据类型 变量名1,变量名n; 或extern 变量名1,变量名n;,注意: 外部变量声明用关键字extern,而外

33、部变量的定义不能用extern,只能隐式定义。 定义外部变量时,系统要给变量分配存储空间,而对外部变量声明时,系统不分配存储空间,只是让编译系统知道该变量是一个已经定义过的外部变量,与函数声明的作用类似。,2005年3月,56,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的作用是什么?如何修改程序使所有函数都可以使用外部变量而又不需要声明?,【例7.24】在一个文件内声明外部变量。,2005年3月,57,【例7.25】在多文件的

34、程序中声明外部变量。,file1.c文件中程序如下: int i; 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文件中程序如下: extern int i; void f2( ) int i=3;printf(“nf2: i=%d“,i); void f3( ) i=3;printf(“nf3: i

35、=%d“,i); ,程序输出结果: f1: i=2 main: i=2 f2: i=3 main: i=2 f3: i=3 main: i=3,声明外部变量,定义外部变量,2005年3月,58,4.寄存器变量(register类别),只有函数内定义的变量或形参可以定义为寄存器变量。寄存器变量的值保存在CPU的寄存器中。 受寄存器长度的限制,寄存器变量只能是char、int和指针类型的变量。,【例7.26】寄存器变量的使用。 main( ) long int sum=0;register int i;for (i=1; i=1000; i+)sum+=i;printf(“sum=%ldn “,s

36、um); ,程序输出结果: sum=500500,2005年3月,59,7.6.3 归纳变量的分类,1按照变量的作用域对变量分类 局部变量 全局变量 2按照变量的生存期对变量分类 静态存储变量 包括:局部静态变量和全局静态变量 动态存储变量 包括:自动变量,2005年3月,60,7.7 函数的存储分类,外部函数: extern int fan(char a,char b) ,静态函数: static int func( ) ,外部函数和静态函数区别: 外部函数允许本程序其他文件中的函数调用 (与外部变量类似)。 静态函数禁止本程序其他文件中的函数调用 (与外部静态变量类似)。,extern可以

37、省略,2005年3月,61,源文件 *.c,运行文件 *.exe,编译,编译,编译,目标文件 *.obj,连接,编译,连接,连接,编译预处理包括:宏定义文件包含条件编译,7.8 编译预处理,2005年3月,62,7.8 编译预处理(续),main() float r,s,c;scanf(“%f”, ,?,如何修 改圆周率,2005年3月,63,#define 宏名 字符串,宏定义的功能:在进行编译前,用字符串原样替换程序中的宏名。这个替换过程称为“宏替换”或“宏展开”,字符串也称为替换文本。,命令的一般格式:,7.8.1 不带参数的宏定义,7.8 编译预处理(续),2005年3月,64,7.8

38、 编译预处理(续),例如:,#define PI 3.14 main() float r,s,c;scanf(“%f”, ,替 换,3.14,3.14,编 译,2005年3月,65,7.8 编译预处理(续),为了增加程序的可读性,建议宏名用大写字母,其他的标识符用小写字母。 双引号中有与宏名相同的字符串不进行替换。 已经定义的宏名可以被后定义的宏名引用。在预处理时将层层进行替换。,说明: 宏定义的作用域是从定义处开始到源文件结束, 但根据需要可用undef命令终止其作用域。形式为:,#undef 宏名,2005年3月,66,【例7.29】不带参数的宏定义。,源程序: #define PI 3.

39、14 #define S PI*r*r #define V 4*S*r/3 main( ) float r;printf(“nInput r:“);scanf(“%f“, ,编译预处理后的程序: main( ) float r;printf(“nInput r:“);scanf(“%f“, ,S,V,S,V,2005年3月,67,命令的一般形式,7.8.2 带参数的宏定义,#define 宏名(形参表) 字符串,功能:在编译预处理时,把源程序中所有带参数的宏名用宏定义中的字符串替换,并且用宏名后圆括号中的实参替换字符串中的形参。,例如:#define MAX(X,Y) (X)(Y)?(X):(

40、Y),7.8 编译预处理(续),2005年3月,68,7.8 编译预处理(续),【例7.30】带参数的宏定义。 #define MAX(x,y) (x)(y)?(x):(y) 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

41、);,2005年3月,69,7.8 编译预处理(续),【例7.31】分析下面程序运行后的输出结果。 #define MA(x) x*(x-1) 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,2005年3月,70,7.8 编译预处理(续),命令的一般形式 格式1: #include

42、格式2: #include “文件名“,7.8.3 文件包含,文件包含是将指定的某个源文件的内容全部包含到当前文件中。用include命令实现。,用格式1,预处理程序仅在TCINCLUDE目录下查找指定文件。用格式2,预处理程序首先在当前目录中查找指定文件,若找不到再到TCINCLUDE目录中查找。,2005年3月,71,7.8 编译预处理(续),例如:调用sin(x) 函数时,要在程序的开头使用如下命令: #include 在预处理时,用math.h文件内容替换 #include 命令行。,2功能在预处理时,将include命令后指定文件的内容替换该命令行。,2005年3月,72,7.9 多

43、文件程序的调试方法,操作步骤如下: 在TC 环境下建立一个工程文件(扩展名为prj),设文件名为test.prj,文件内容如下:file1.cfile2.cfiile3.c 若这个文件不在当前盘或当前路径下,需要在文件名前加盘符和路径。如果已经将源文件编译成目标文件,可在工程文件中直接写目标文件名。,1. 使用工程文件将多个文件连接成一个可执行文件的方法,例如:将file1.c、file2.c和file3.c合并成一个可执行文件。,2005年3月,73,7.9 多文件程序的调试方法(续), 在TC主菜单的“Project”下拉菜单中选择“Project name”项,输入文件名test.prj

44、(文件名前也可以加盘符和路径)。 在TC环境下,按Ctrl+F9,系统首先找到工程文件test.prj,然后将file1.c、file2.c和file3.c分别进行编译,若编译没通过,根据出错信息检查、修改源程序,然后再按Ctrl+F9重新编译。若编译通过,系统自动生成三个对应的目标文件:file1.obj 、file2.obj 和 fiile3.obj。接着系统自动进行连接,连接成功则生成test.exe并自动执行该程序。,2005年3月,74,7.9 多文件程序的调试方法(续),2. 使用文件包含命令将多个文件连接成一个可执行文件的方法,以例7.27为例,分析文件包含后源程序的情况。,2005年3月,75,7.9 多文件程序的调试方法(续),file3.c,#include “file2.c“ #include “file3.c“,file1.c,A,file2.c,B,C,B,C,A,file1.c,预处理前,预处理后,2005年3月,76,第章结束,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报