《解析C程序设计第3章自定义函数设计.ppt》由会员分享,可在线阅读,更多相关《解析C程序设计第3章自定义函数设计.ppt(73页珍藏版)》请在三一办公上搜索。
1、第3章 自定义函数设计,2023/7/2,解析C程序设计第3章 自定义函数设计,2,本章内容,最大值和最小值问题条件运算符 函数的定义 函数的调用 函数的返回 参数的传递 函数的声明 交换两个变量值的问题 变量的作用域 变量的存储类型,2023/7/2,解析C程序设计第3章 自定义函数设计,3,前面的所有程序都是由一个主函数main()组成,程序的所有操作都在主函数中完成。(当然也包含一些库函数)对于小程序可以这样做,但是,对于一个有一定规模的程序这样做就不合适了。,2023/7/2,解析C程序设计第3章 自定义函数设计,4,事实上,C程序可以只包含一个主函数也可以包含一个主函数和若干个其它函
2、数(库函数和自定义函数)C语言是一个函数式语言。,2023/7/2,解析C程序设计第3章 自定义函数设计,5,C函数分类,(1)用户自定义函数(包括主函数);(2)系统提供的库函数。由C系统开发商提供,程序员可以直接调用。自定义函数以下简称函数。下面通过一个简单问题来初步了解自定义函数的用法。,2023/7/2,解析C程序设计第3章 自定义函数设计,6,3.1 最大值和最小值问题,2023/7/2,解析C程序设计第3章 自定义函数设计,7,问题的提出,例3-1 由用户输入三个整数,编程求解三个数的最大值和最小值。,2023/7/2,解析C程序设计第3章 自定义函数设计,8,问题的分析,【分析】
3、根据前面所学,本问题将可以所有功能都在主函数中完成。也可以用两个函数分别完成求最大值和最小值,在主函数中调用这两个函数即可。这样的好处是,可以实现代码共享,而且使相对独立功能的代码分离,便于维护。求最大值和最小值可以使用条件运算符完成,当然还有其他办法(你知道吗?)。另外还涉及到函数的定义、函数的调用、函数值的返回、参数的传递、函数的声明等基本知识。下面逐步介绍。,2023/7/2,解析C程序设计第3章 自定义函数设计,9,条件表达式运算符,一般形式:expr1?expr2:expr3运算规则:,例 求 a+|b|printf(“a+|b|=%dn”,b0?a+b:a-b);,条件运算符可嵌套
4、 如 x0?1:(x0?-1:0)优先级:13,结合方向:自右向左 如 ab?a:cd?c:d ab?a:(cd?c:d)expr1、expr2、expr3类型可不同,表达式值取较高的类型,2023/7/2,解析C程序设计第3章 自定义函数设计,10,求x和y的最大值,max=xy?x:y;,2023/7/2,解析C程序设计第3章 自定义函数设计,11,函数的定义,合法标识符,函数返回值类型:缺省int型,无返回值void,函数体,例 有参函数(现代风格)int max(int x,int y)int z;z=xy?x:y;return(z);,例 无参函数void printstar()pr
5、intf(“*n”);或void printstar(void)printf(“*n”);,参数:传递数据信息的通道,2023/7/2,解析C程序设计第3章 自定义函数设计,12,传统风格的函数定义,函数类型 函数名(形式参数表)形参类型说明声明部分执行部分,例 有参函数(传统风格)int max(x,y)int x,y;int z;z=xy?x:y;return(z);,一般情况下,均使用现代风格定义函数,并且要指定函数类型。,2023/7/2,解析C程序设计第3章 自定义函数设计,13,函数定义说明,函数类型表示在调用了该函数后,其返回值的数据类型。可为:int、char、float、do
6、uble等。如果函数无数据返回时,应使用void 作类型定义符。注意,省略了类型说明符,C编译器认为函数返回值为一个整型值类型(int)。函数名即函数的名称,是由用户取的合法标识符。C语言的关键字不能作函数名。自定义函数的名称可以使用库函数名,但这时库函数被屏蔽。形式参数表是一个用逗号分隔的变量表,当函数被调用时这些变量接受调用参数的值。相当于函数调用时传递信息的通道。注意:每个参数必须指明类型!在函数的定义中,如果没有函数体,即函数什么功能都不做,我们称为空函数。空函数的功能主要是在程序设计中,留出该函数的功能,以后在需要的时候补充上去。,2023/7/2,解析C程序设计第3章 自定义函数设
7、计,14,特别注意,(1)函数不能单独运行,函数可以被主函数或其它函数调用,也可以调用其它函数,但是不能调用主函数。(2)C规定,函数体的声明部分和执行部分应严格划分,且声明部分放在函数体的开始。,2023/7/2,解析C程序设计第3章 自定义函数设计,15,课堂练习,定义两个函数:求两个整数的最大值函数求两个整数的最小值函数,2023/7/2,解析C程序设计第3章 自定义函数设计,16,int max(int x,int y)return(xy?x:y);,int min(int x,int y)return(xy?x:y);,2023/7/2,解析C程序设计第3章 自定义函数设计,17,主
8、调函数与被调函数,C语言程序是由若干个函数组成的,各函数在结构上是独立的,但它们所处理的数据却是相互联系的。一个函数定义好后,就必须用一定的方式去调用它。一个函数调用另一个函数,将调用的函数称为主调函数,将被调用的函数称为被调函数。主调函数和被调函数具有数据传递的关系,其传递的实施是通过函数的参数来实现的。,2023/7/2,解析C程序设计第3章 自定义函数设计,18,函数的调用,一般形式 函数名(实参表);,如:printf(“Hello,World!n”);max(10,20);,2023/7/2,解析C程序设计第3章 自定义函数设计,19,int max(int x,int y)retu
9、rn(xy?x:y);void main()int a,b,c,d,t;.t=max(a+b,c+d);,函数调用,被调函数,主调函数,2023/7/2,解析C程序设计第3章 自定义函数设计,20,函数调用的几种方式,(1)作为函数语句调用。函数一般无返回值。例:printf(“Hello,World!n”);(2)作为函数表达式调用。例:m=max(a,b)*2;(3)作为函数参数调用。例:printf(“%d”,max(a,b);m=max(a,max(b,c);,2023/7/2,解析C程序设计第3章 自定义函数设计,21,函数调用说明,如果调用的是无参函数,则“实际参数表”可以没有,但
10、括号()不能省略。如果实参表包含多个实参,则各参数间用逗号隔开。实参与形参的个数应相等、类型应一致。实参与形参按顺序对应,一一传递数据。特别说明:如果实参表包括多个实参,对实参求值的顺序并不确定,有的系统自左至右,有的则是自右至左。TurboC是按自右而左的顺序求值的。读者对自已的系统可编程试之。,2023/7/2,解析C程序设计第3章 自定义函数设计,22,函数调用说明,函数不能嵌套定义,即在一个定义好的函数中,又定义另一个函数。但是函数之间允许相互调用,也允许嵌套调用。但main函数不能被调用。函数还可以自己调用自己,称为递归调用。,2023/7/2,解析C程序设计第3章 自定义函数设计,
11、23,例3-2:求两个整数的最大值和最小值,【分析】首先定义两个函数:求最大值和最小值,然后在主函数中调用。#include/*定义求最大值的函数*/void maxmum(int x,int y)printf(max=%dn,(xy)?x:y);/*求x与y的最大值*/*定义求最小值的函数*/void minmum(int x,int y)printf(min=%dn,(xy)?x:y);/*求x与y的最小值*/void main()/*主函数*/int a,b;/*定义变量*/scanf(%d,%d,/*调用函数,求a与b的最小值,此处函数作语句*/,2023/7/2,解析C程序设计第3章
12、 自定义函数设计,24,函数的返回,返回语句形式:return(表达式);或 return 表达式;或 return;功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数说明:函数中可有多个return语句,但只能返回唯一的函数值若无return语句,遇 时,自动返回调用函数,返回值是一个不确定的值若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换-函数调用转换void型函数:表示“空类型”或“无类型”,例 无返回值函数 void swap(int x,int y)int temp;temp=x;x=y;y=temp;,例 有返回值函数int maxmum
13、(int x,int y)int z;z=(xy)?x:y;return(z);/*返回最大值*/,2023/7/2,解析C程序设计第3章 自定义函数设计,25,函数返回不确定值,int printstar()printf(*);void main()int a;a=printstar();printf(%d,a);,输出:*10,void printstar()printf(*);void main()int a;a=printstar();printf(%d,a);,编译错误:No an allowed type in function main,2023/7/2,解析C程序设计第3章 自
14、定义函数设计,26,函数返回值类型转换,#include void main()float a,b;int c;scanf(%f,%f,这个程序能运行吗?运行能得到正确结果吗?,float,2023/7/2,解析C程序设计第3章 自定义函数设计,27,例3-2:求两个整数的最大值和最小值,【分析】在前面程序的基础上使用return语句返回最大值和最小值,然后在主函数中调用。/*LI3_2_2.c*/#include int maxmum(int x,int y)int max;max=(xy)?x:y;return(max);int minmum(int x,int y)int min;min
15、=(xy)?x:y;return min;void main()int a,b;scanf(%4d,%4d,2023/7/2,解析C程序设计第3章 自定义函数设计,28,函数参数,形参与实参形式参数:定义函数时函数名后面括号中的变量名实际参数:调用函数时函数名后面括号中的表达式,例 比较两个数并输出大者,#include void main()int a,b,c;scanf(%d,%d,2023/7/2,解析C程序设计第3章 自定义函数设计,29,参数传递值传递方式,值传递方式方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值特点:形
16、参与实参占用不同的内存单元单向传递,2023/7/2,解析C程序设计第3章 自定义函数设计,30,参数传递地址传递方式,地址传递方式:函数调用时,将数据的存储地址作为参数传递给形参特点:形参与实参占用同样的存储单元“双向”传递实参和形参必须是地址常量或变量,2023/7/2,解析C程序设计第3章 自定义函数设计,31,#include void main()float a,b;int c;scanf(%f,%f,这个程序能运行吗?运行能得到正确结果吗?,C语言规定:被调用函数必须是已存在的函数!,2023/7/2,解析C程序设计第3章 自定义函数设计,32,为此,C提供了函数原型的机制。即函数
17、声明后即可调用。,2023/7/2,解析C程序设计第3章 自定义函数设计,33,函数声明,对被调用函数要求:必须是已存在的函数库函数:#include 用户自定义函数:函数类型声明函数声明一般形式:函数类型 函数名(形参类型 形参名,.);或:函数类型 函数名();作用:告诉编译系统函数类型、参数个数及类型,以便检验函数定义与函数声明不同函数声明位置:程序的数据声明部分(函数内或外)下列情况下,可不作函数声明若函数返值是char或int型,系统自动按int型处理被调用函数定义出现在主调函数之前有些系统(如Borland C+)要求函数声明指出函数返值类型和形参类型,并且对void 和 int
18、型函数也要进行函数声明,2023/7/2,解析C程序设计第3章 自定义函数设计,34,函数声明举例,float add(float,float);/*函数声明*/void main()float a,b,c;scanf(%f,%f,2023/7/2,解析C程序设计第3章 自定义函数设计,35,例3-1问题的实现,#include/*库函数的声明*/int maxmum(int x,int y,int z);/*自定义函数声明*/int minmum(int x,int y,int z);/*自定义函数声明*/void main()/*主函数*/int a,b,c,max,min;clrscr(
19、);/*清屏*/scanf(%d,%d,%d,/*函数的返回值*/,2023/7/2,解析C程序设计第3章 自定义函数设计,36,C程序结构,2023/7/2,解析C程序设计第3章 自定义函数设计,37,为什么要使用函数,使用函数可以控制任务的规模 使用函数可以控制变量的作用范围 使用函数可以由多人分工协作完成程序的开发 使用函数,可以重新利用已有的、调式好的、成熟的程序模块(函数),2023/7/2,解析C程序设计第3章 自定义函数设计,38,举一反三,例3-3:比较年龄的大小。【分析】本例实际上是输入两个整型数据后再比较其大小。#include void main()int yourAge
20、,hisAge,max;clrscr();/*清屏函数,在stdio.h中声明*/printf(Please enter your age:);scanf(%d,条件运算符的运用,2023/7/2,解析C程序设计第3章 自定义函数设计,39,例3-4:计算两个实数之和,【分析】首先要输入两个实数,然后调用求两个实数和的函数。#include/*定义求两个数和的函数*/float Add(float a,float b)/*自定义函数*/return(a+b);void main()/*主函数*/float x,y;double sum=0.0;printf(Input two floating
21、 decimals:);scanf(%f%f,/*输出x和y相加之和*/,函数操作,2023/7/2,解析C程序设计第3章 自定义函数设计,40,用宏定义和函数实现同样的功能,#define MAX(x,y)(x)(y)?(x):(y).main()int a,b,c,d,t;.t=MAX(a+b,c+d);宏展开:t=(a+b)(c+d)?(a+b):(c+d);,int max(int x,int y)return(xy?x:y);void main()int a,b,c,d,t;.t=max(a+b,c+d);,2023/7/2,解析C程序设计第3章 自定义函数设计,41,思考题,在同一
22、程序不同的函数中定义相同的变量名是否对其它函数中的相同变量有影响?,int fun1()int x,y;int sum;sum=x+y;,int fun2()int x,y;int t;t=x*y;,2023/7/2,解析C程序设计第3章 自定义函数设计,42,3.2 交换两个变量值的问题,如果a的值为3,b的值为5,怎样将a的值变为5,b的值变为3呢?最简单的办法就是在main函数中在定义一个变量c作为中间的交换变量,其程序如下:#include void main()int a=3,b=5,c;printf(Before Exchange:a=%d,b=%dn,a,b);c=a;a=b;b
23、=c;printf(After Exchange:a=%d,b=%dn,a,b);程序的运行情况:Before Exchange:a=3,b=5After Exchange:a=5,b=3本例中的c=a;a=b;b=c;完成a与b两个变量的交换,也称为交换器。但是怎样使用函数来实现交换两个变量的值呢?,2023/7/2,解析C程序设计第3章 自定义函数设计,43,问题的提出,例3-7:用函数来实现交换两个变量的值。,2023/7/2,解析C程序设计第3章 自定义函数设计,44,问题的分析,可以定义一个函数swap来交换两个变量的值,在main函数中给出a和b的值,然后将这两个变量的值传到自定义
24、函数swap中。可以在main函数和swap函数中分别显示a和b的值,查看a和b的值交换情况。形参和实参是“值传递”,根据变量的三要素,在内存中它们分别占用两个不同的存储空间(后面的存储空间概念均指在内存中的存储空间),通过“值传递”的参数不能传回主调函数。因此,在函数swap中可以实现形参的交换,但函数调用完成后,形参不复存在,main函数中的变量值仍未改变。那么造成上述结果的原因是什么呢?有怎样解决呢?为了解决这类问题,须了解变量的作用域和存储类型。,2023/7/2,解析C程序设计第3章 自定义函数设计,45,变量的作用域与存储类型,变量是对程序中数据的存储空间的抽象,编译或函数调用时为
25、其分配内存单元,10,程序中使用变量名对内存操作,2023/7/2,解析C程序设计第3章 自定义函数设计,46,变量的作用域与存储类型,变量的属性数据类型:变量所持有的数据的性质(操作属性)存储属性存储器类型:寄存器、静态存储区、动态存储区生存期:变量在某一时刻存在-静态变量与动态变量作用域:变量在某区域内有效-局部变量与全局变量变量的存储类型auto-自动型register-寄存器型static-静态型extern-外部型变量定义格式:存储类型 数据类型 变量表;,如:int sum;auto int a,b,c;register int i;static float x,y;,变量是对程序
26、中数据的存储空间的抽象,2023/7/2,解析C程序设计第3章 自定义函数设计,47,局部变量内部变量,定义:在函数内定义,只在本函数内有效说明:main中定义的变量只在main中有效 不同函数中同名变量,占不同内存单元 形参属于局部变量 可定义在复合语句中有效的变量 局部变量可用存储类型:auto、register、static(默认为auto),#define N 5#include void main()int i;int aN=1,2,3,4,5;for(i=0;iN/2;i+)int temp;temp=ai;ai=aN-i-1;aN-i-1=temp;for(i=0;iN;i+)p
27、rintf(%d,ai);,运行结果:5 4 3 2 1,#include void main()int a,b;a=3;b=4;printf(main:a=%d,b=%dn,a,b);sub();printf(main:a=%d,b=%dn,a,b);void sub()int a,b;a=6;b=7;printf(sub:a=%d,b=%dn,a,b);,2023/7/2,解析C程序设计第3章 自定义函数设计,48,全局变量外部变量,定义:在函数外定义,可为本文件所有函数共用 有效范围:从定义变量的位置开始到本源文件结束,及有extern声明的其它源文件,外部变量声明:extern 数据类
28、型 变量表;,外部变量定义与外部变量声明不同,若外部变量与局部变量同名,则外部变量被屏蔽,外部变量可用存储类型:缺省extern 或 static,应尽量少使用全局变量,因为:全局变量在程序全部执行过程中占用存储单元降低了函数的通用性、可靠性,可移植性降低程序清晰性,容易出错,定义 说明次数:只能1次 可说明多次位置:所有函数之外 函数内或函数外分配内存:分配内存,可初始化 不分配内存,不可初始化,2023/7/2,解析C程序设计第3章 自定义函数设计,49,例3-8:使用函数求两个变量的最大值、最小值、平均值,【分析】每个函数通过返回值方式只能返回一个值,而本例要求3个值。解决办法之一是:函
29、数返回平均值,而最大值与最小值通过全局变量的形式返回。,2023/7/2,解析C程序设计第3章 自定义函数设计,50,例3-8程序,#include float Max=0,Min=0,a=10,b=20;/*定义Max和Min为最大值和最小值全局变量*/float average();/*函数声明*/void main()float a,ave;printf(Input a,b:);scanf(%f,%f,/*返回平均值*/,2023/7/2,解析C程序设计第3章 自定义函数设计,51,例3-7问题的实现,/*LI3_7_1.c*/#include void swap(int x,int y
30、);void main()int a=3,b=5;printf(11 a=%d,b=%dn,a,b);/*调用交换函数之前*/swap(a,b);/*调用交换函数swap*/printf(12 a=%d,b=%dn,a,b);/*调用交换函数之后*/*定义交换两个变量的值的函数*/void swap(int x,int y)/*函数定义*/int a;printf(21 x=%d,y=%dn,x,y);/*交换变量值之前*/a=x;x=y;y=a;/*交换器:交换变量x,y的值*/printf(22 x=%d,y=%dn,x,y);/*交换变量值之后*/,2023/7/2,解析C程序设计第3章
31、 自定义函数设计,52,例3-7问题的实现,/*LI3_7_2.c*/#include int a=3,b=8;/*全局变量*/void swap();void main()b=5;printf(11 a=%d,b=%dn,a,b);/*调用交换函数之前*/swap();/*调用交换函数swap*/printf(12 a=%d,b=%dn,a,b);/*调用交换函数之后*/void swap()/*函数定义*/int t;printf(21 a=%d,b=%dn,a,b);/*交换变量值之前*/t=a;a=b;b=t;/*本行的3句:交换变量a,b的值*/printf(22 a=%d,b=%d
32、n,a,b);/*交换变量值之后*/,2023/7/2,解析C程序设计第3章 自定义函数设计,53,思考题,怎样能够通过参数传递真正实现a与b的交换呢?可以使用指针来完成,将在后面章节讲述。,2023/7/2,解析C程序设计第3章 自定义函数设计,54,存储类型的提出,#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()printf(max=%d,max(a,b);int a=13,b=-8;,extern int a,b;,前面讲过以下程序段,在程序的最后定义全局变量a、b有意义吗?要使它能使用,必须通过通过ext
33、ern int a,b;语句扩展作用域。这就是变量的存储类型所要做的事情。,2023/7/2,解析C程序设计第3章 自定义函数设计,55,动态变量与静态变量,动态变量与静态变量,是从变量的生存期角度来分类的。1、存储方式 静态存储:程序运行期间分配固定存储空间。动态存储:程序运行期间根据需要动态分配存储空间。2、内存用户区,3、生存期 静态变量:从程序开始执行到程序结束。动态变量:从包含该变量定义的函数开始执行至函数执行结束。,2023/7/2,解析C程序设计第3章 自定义函数设计,56,变量的存储类型,局部变量默认为auto型register型变量个数受限,且不能为long,double,f
34、loat型局部static变量具有全局寿命和局部可见性局部static变量具有可继承性(下次进入函数该值还存在)extern不是变量定义,可扩展外部变量作用域,2023/7/2,解析C程序设计第3章 自定义函数设计,57,自动变量auto,在C语言中,函数内部定义的变量(局部变量)缺省为自动变量(automatic variable)。自动变量是最常用的。关键字auto能够显式地指定存储类别。显式定义 auto int x,y;隐含定义 等价 int x,y;实际上关键字“auto”可以省略,auto不写则隐含确定为“自动存储类别”,即动态存储方式。程序中大多数变量属于自动变量。,2023/7
35、/2,解析C程序设计第3章 自定义函数设计,58,auto的作用域,main()int x=1;void prt(void);int x=3;prt();printf(“2nd x=%dn”,x);printf(“1st x=%dn”,x);void prt(void)int x=5;printf(“3th x=%dn”,x);,运行结果:3th x=52nd x=31st x=1,2023/7/2,解析C程序设计第3章 自定义函数设计,59,寄存器变量register,对于使用频繁的变量,可以使用register声明为寄存器变量,其值存储在CPU中,加快了运行速度。如:register in
36、t x;register char c;说明:只有局部自动变量和形式参数可以作为寄存器变量,其余非法。一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。一般来讲只允许int和char才能定义为寄存器变量,但目前大多数系统都支持指针型变量定义为寄存器变量。局部静态变量不能定义为寄存器变量,即不能定义:register static int x;,对一个变量只能声明一个存储类别。当今优化的编译系统,能够自动识别使用频繁的变量,从而自动的将这些变量放在寄存器中。因此程序设计者实际上根本不需要去声明寄存器变量。,2023/7/2,解析C程序设计第3章 自定义函数设计,60,用stati
37、c声明局部变量,有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,以便下一次调用该函数时可以使用上一次调用的最后结果。这时就应该指定该局部变量为“静态局部变量”。,#include void main()void increment(void);increment();increment();increment();void increment(void)int x=0;x+;printf(“%dn”,x);,运行结果:111,#include void main()void increment(void);increment();increment();increment();v
38、oid increment(void)static int x=0;x+;printf(“%dn”,x);,运行结果:123,例:局部静态变量值具有可继承性,2023/7/2,解析C程序设计第3章 自定义函数设计,61,例3-10:计算15的阶乘,#include int fac(int i);/*计算阶乘的函数声明*/void main()int i,r;/*如果i值频繁使用,编译器会自动以寄存器变量存放*/for(i=1;i=1)f=f*i;/*f的初值为上次计算的f值*/return(f);,2023/7/2,解析C程序设计第3章 自定义函数设计,62,用extern声明外部变量,外部变
39、量(即全局变量)是在函数的外部定义的,它的作用域为从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。有时需要用extern来声明外部变量,以扩展外部变量的作用域。在一个文件内声明外部变量 如果全局变量在后面定义,而在前面的函数中要使用,则必须在使用前用extern声明该全局变量。如:extern int Abc;也可以省略int成:extern Abc;,2023/7/2,解析C程序设计第3章 自定义函数设计,63,例3-11:求两个全局变量的最大值,/*LI3_11.c*/#include int max(int x,
40、int y);/*函数声明*/void main()extern A,B;/*声明外部变量*/int r;r=max(A,B);printf(%d,r);int max(int x,int y)/*函数定义*/int z;z=xy?x:y;return(z);int A=13,B=-8;/*定义外部变量*/,注:extern A,B;等价于:extern int A,B;,2023/7/2,解析C程序设计第3章 自定义函数设计,64,int p=1,q=5;float f1(int a)int b,c;.int f3().char c1,c2;char f2(int x,int y)int i
41、,j;main()int m,n;.,c1,c2的作用范围,p,q的作用范围,2023/7/2,解析C程序设计第3章 自定义函数设计,65,在多个文件的程序中声明外部变量,一个C程序可以由一个或多个源程序文件组成。如果一个程序包含两个文件,在两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num。而应该在任一个文件中定义外部变量Num,而在另一个文件中用extern对Num作“外部变量声明”。如:,file1.c:int Num;main()int power(int);int b=3,c,d,m;Num=3;m=2;c=Num*b;d=powe(m);,fil
42、e2.c:extern Num;power(int n)int i,y=1;for(i=1;i=n;i+)y*=Num;return(y);,C在编译时遇到extern,先在本文件中找外部变量的定义,如果找到,就在本文件中扩展作用域。如果找不到,就在连接时从其它文件中找外部变量的定义,如果找到,就将作用域扩展到本文件。如果找不到,按出错处理。,2023/7/2,解析C程序设计第3章 自定义函数设计,66,例:输出ab和a的m次方,#include int a;void main()int power(int n);int b=3,c,d,m;printf(Enter the number a
43、and its power:n);scanf(%d,%d,extern int a;int power(int n)int i,y=1;for(i=1;i=n;i+)y*=a;return(y);,file1.c:,file2.c:,2023/7/2,解析C程序设计第3章 自定义函数设计,67,用static声明外部变量,有时在程序设计中,希望某些外部变量只限于被本文件引用,而不能被其它文件引用,这时可以在定义外部变量时加一个static声明。,file1.c:static int A;main()int power(int);int b=3,c,d,m;A=3;m=2;c=A*b;d=pow
44、e(m);,file2.c:extern int A;power(int n)int i,y=1;for(i=1;i=n;i+)y*=A;return(y);,在file1.c中定义了一个全局变量A,但它用static声明,因此只能用于本文件。虽然在file2.c文件中用了extern int A;,但file2.c文件中无法使用file1.c中的全局变量A。这种加上static声明只能用于本文件的外部变量(全局变量)称为静态外部变量。,无法使用A,2023/7/2,解析C程序设计第3章 自定义函数设计,68,作用域与生存期的例子,文件名:file1.c,2023/7/2,解析C程序设计第3章
45、 自定义函数设计,69,举一反三,例3-12:计算不同类型变量的自加。#include void fun(int i);void main()int i;fun(0);fun(1);fun(2);void fun(int i)int a=3;/*每次执行该函数时均要定义和赋值*/static int b=3;/*第一次执行该函数时定义和赋值*/a+;/*a的基数为3*/b+;/*使用上一次的b值作基数相加*/printf(No:%d-a=%d,b=%dn,i,a,b);,静态变量的应用,2023/7/2,解析C程序设计第3章 自定义函数设计,70,例3-13:计算一个数的立方,#include
46、 void cude();void main()extern N;/*扩展全局变量N的作用域*/clrscr();printf(Input a number:);scanf(%d,外部变量的应用,2023/7/2,解析C程序设计第3章 自定义函数设计,71,建 议,学好程序设计语言的唯一途径是上机练习你的编程能力与你在计算机上投入的时间成正比,2023/7/2,解析C程序设计第3章 自定义函数设计,72,习题3,教材:习题3.3 3.7 3.9。教材:习题3.2 3.6 3.12。,2023/7/2,解析C程序设计第3章 自定义函数设计,73,思考题,怎样编写比较复杂的带有控制流程的程序?如:满足某种条件执行某段程序;重复计算某种运算:12,