C语言课件第七章本.ppt

上传人:本田雅阁 文档编号:2143432 上传时间:2019-02-21 格式:PPT 页数:82 大小:785.01KB
返回 下载 相关 举报
C语言课件第七章本.ppt_第1页
第1页 / 共82页
C语言课件第七章本.ppt_第2页
第2页 / 共82页
C语言课件第七章本.ppt_第3页
第3页 / 共82页
亲,该文档总共82页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《C语言课件第七章本.ppt》由会员分享,可在线阅读,更多相关《C语言课件第七章本.ppt(82页珍藏版)》请在三一文库上搜索。

1、共 81页 第 1 页,第七章,函 数,共 81页 第 2 页,本章要点 函数的定义 函数的调用 函数参数的传递方式 变量的作用域和存储方法 内部函数和外部函数,共 81页 第 3 页,C程序是函数的集合体,每个函数是一个独立的程序模块; 由一个主函数和若干个子函数组成,程序总是从主函数开始执行; 所有子函数地位平等,可互相调用、自我调用。 函数可集中或分散存放在一个或多个源程序文件中。 引入函数的优点: 减少重复编写程序的工作量;使程序便于调试和阅读。,函数,C语言程序的结构,7.1 函数的概念和函数的定义,共 81页 第 4 页,main: 主函数 e, d, h ,g 被多次调用 a,

2、b, c,d, e, f,g, h, 相互调用,函数是C程序的最小单元。主函数可以调用其它函数,其它函数可以相互调用.,共 81页 第 5 页,函数调用举例,main() /* 主函数 */ printstar(); /*调用printstar函数画*/ print_message(); /*调用print _message函数写字*/ printstar(); /*调用printstar函数画*/ printstar() /*printstar函数*/ printf(“n*”); print_message() /* print_message函数*/ printf(“n Hello! ”)

3、; ,运行结果:* Hello! *,共 81页 第 6 页,一个c程序由一个或多个源文件组成,# include “lx2.c” # include “lx3.c” main() printstar(); print_message(); printstar(); printstar() printf(“n*”); print_message() printf(“n Hello! ”); ,共 81页 第 7 页,数学函数 #include math.h 字符和字符串函数 ctype.h, string.h I/O函数 #include stdio.h 动态存储分配函数,C函数的分类,共 8

4、1页 第 8 页,一、定义形式: 类型标识符 函数名(形式参数表) 形式参数说明 说明与定义部分 语句 ,7.1.2 函数的定义,有参函数定义形式,有参函数定义形式,共 81页 第 9 页,无参函数的定义形式: 类型标识符 函数名( ) 说明部分 语句 ,例:print_message( ) printf(“How are you !n”); ,例:dummy ( ) ,没有数据类型说明、 形参和形参说明,函数体为空。,共 81页 第 10 页,long facto ( n ) int n; long s=1;int i; for (i=1; i=n; i+) s *= i; return (

5、s); ,函数名,形式参数列表,函数类型,形式参数说明,函数体,函数返回,求阶乘函数facto的定义,函数的定义(举例),共 81页 第 11 页,main( ) int a,b,c; int max(); scanf(”%d,%d”, ,形式参数列表:是用,分开的一组变量,用来接收调用时传入的数据,形式参数说明:在 外面对形式参数的类型进行说明,函数调用,求两个变量的最大值,函数的定义(举例),函数声明,共 81页 第 12 页,二、 形式参数和实际参数 形式参数: 形参调用前不占内存单元,调用时占用,调用后释放 形参是函数的内部变量,只在函数内部才有意义。 对每个形参必须指明其名字和数据类

6、型。 实际参数: 实参必须有确定的值,可以是常量,变量或表达式。 实参与形参的类型、个数必须一致。,共 81页 第 13 页,7.1.3 函数的调用,1. 函数调用的一般形式为: 函数名(实际参数列表); 或 函数名(实际参数列表) 实参的数量、类型和排列顺序必须与函数定义时形参表中形参的数量、类型和排列顺序一致。,2. 执行过程:,在一个函数中调用另一个函数时,程序将控制从调用函数处转移到被调用函数,并且执行被调用函数。 在执行完被调用函数的所有语句或者遇到return语句时,程序的控制要返回到调用函数中原来调用函数的地方继续执行。,共 81页 第 14 页,例:调用max函数的程序 mai

7、n() int a,b,c; int max(); scanf(“%d,%d“, ,函数调用,int max(x,y) int x,y; int z; if(xy)z=x; else z=y; return(z); ,实际参数,形式参数,返回函数值,接收 返回值,程序执行顺序?,共 81页 第 15 页,/*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*11*/ /*12*/ /*13*/ /*14*/ /*15*/ /*16*/,main() int a,b,c; int max(); scanf(“%d,%d“, ,断点,保护断点和 现场,转向11,入口,返回断点 恢复现场

8、带回函数值,函数执行过程,共 81页 第 16 页,(1) 函数语句 (把函数调用作为一个语句) 一般形式:函数名(实际参数表); 此时不要求函数带回值,只要求函数完成一定的操作。 例如: printstar( );,3. 函数调用的几种方式,(2) 函数表达式(函数调用出现在表达式中) 一般形式:变量名=函数表达式 这时要求函数带回一个确定的值以参加表达式的运算。 例如:c=3+max(a, b);,注意:无返回值函数的调用,不能出现在表达式中。,函数调用作为一个函数的实参。 例如:m = max( a, max(b, c) );,(3) 函数参数 (函数调用出现函数参数中),值传递: 在调

9、用函数时,实参将值传递给形参。 C语言规定,实参对形参的数据传递是“值传递”,即单向传递。 在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。 因此,在执行一个被调用函数时,形参的值如果发生变化,并不会改变主调函数中实参的值。,7.1.4 函数参数的传递方式,共 81页 第 18 页,例如: void add(int a, int b) a+=3; b+=6; printf(“a=%d, b=%dn”, a,b); ,main( ) int x=1, y=2; add(x, y); printf(“x=%d, y=%dn”, x

10、, y); ,输出结果: a=4,b=8,值传递,x=1,y=2,执 行 函 数 体,返回,共 81页 第 19 页,值传递的优点:被调用的函数不可能改变调用函数 中变量的值,而只能改变它的局部的临时副本。,值传递的缺点:每个形式参数仅能传递一个数据, 不适用需要在函数之间传递大量数据。,地址传递:将实参的地址传递给形参,实参和 形参指向同一内存空间,对形参的修改,可以直 接影响实参。,7.1.4 函数参数的传递方式(续),共 81页 第 20 页,7.1.5 函数的返回值,2. 函数的返回值语句: return语句 一般形式: return (表达式); 或 return 表达式;,定义:通

11、过函数调用使主调函数得到一个确定 的值,称为函数的返回值。,注意不要丢掉;,可以省略括号,功能:将表达式的值带回主调函数。,共 81页 第 21 页,说明:,一个函数中可以有多个return语句,但是一次 函数执行只能执行其中的一个。当执行到某个 return语句时,则终止函数执行,并带回函数值。,fun(int x) if(x1) return 2*x+1; else if(x=10) return x* x; else return 3*x10;,共 81页 第 22 页,说明(续):,若函数体内没有return语句,就一直将函数执行 完,再返回调用函数,返回一个不确定的值。, retur

12、n后面可以无“返回值”(即 return ;),则 该return语句只起到 终止函数执行,返回主调 函数的作用。,共 81页 第 23 页,int max(x,y) int x,y; int z; if (xy) z=x; else z=y; return(z); ,返回整型 函数值,int max(x,y) int x,y; int z; if (xy) z=x; else z=y; return; ,无返回值,max(x,y) int x,y; int z; if (xy) z=x; else z=y; ,无返回语句 在此返回,缺省类型说明,函数返回值,共 81页 第 24 页,3. 函

13、数值的类型,函数定义时应该指定函数的类型(即函数值的类型),应该与return语句的类型一致。,说明:,凡不加类型说明的函数,一律自动按整型处理。,如果函数类型和return语句的类型不一致,以函 数类型为准。对数值型数据,可以自动进行类型 转换。既函数类型决定返回值的类型。,如果函数无返回值,可以将函数定义为“无类 型”void (或称“空类型”)。,例如: void print_star(),注意:函数中没有return语句,函数带回的是一个不确定的值。为明确表示不带回值,可以用void定义。,共 81页 第 25 页,例:编写计算 的程序。,程序运行结果:s=3.597740,调用函数时

14、,变量做函数实参,它和对应的形参各自占用 独立的存储单元。,共 81页 第 26 页,例:阅读程序 float add (x, y) float x, y; float z; z=x+y; return (z); main( ) float a, b; scanf(“%f, %f“, ,程序运行: 3.6, 5.5 ,sum is 9.100000,共 81页 第 28 页,7.1.6 函数的说明, 对被调用函数说明的前提条件,被调用函数必须是已存在的函数,如用户自定义函数或库函数。,2. 被调用函数是用户自定义函数的函数说明,同变量一样,函数的调用也应该遵循“先说明,后使用”的原则。,如使用

15、用户自定义函数,而且主调函数和被调用函数在同一个文件中,应该在主调函数中说明被调函数的类型。其说明形式如下:,共 81页 第 29 页,函数说明的一般形式: 类型标识符 函数名(类型1,类型2,); 或类型标识符 函数名(类型1 形参1,类型2 形参2,); 功能:通知编译程序函数值是什么类型,有多少参数及它们各自的类型,为编译程序进行类型检查提供依据。,main() float add(float x,float y); float a, b, c; scanf(“ %f, %f”, ,/*定义add函数*/ float add (float x,float y) float z; z=x+

16、y; return (z); ,对被调用函数的说明,作为表达式被调用,运行结果: 3.6, 5.5 sum is 9.100000,或:类型标识符 函数名();,共 81页 第 30 页,3. 函数说明和函数定义的区别,函数说明的作用是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。,函数定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。,函数说明与函数定义的首部唯一区别:函数说明语句的( )之后必须有分号,而函数定义首部的( )之后没有分号。,共 81页 第 31 页,4. 以下

17、三种情况可以省略被调用函数的说明,函数的返回值为整型或字符型时,可以不进行 函数声明,系统按整型处理。,main( ) int a,b,c; scanf (“%d,%d”, ,可省略函数说明,该函数没有加类型说明,为整型函数.,共 81页 第 32 页,被调用函数的定义在主调函数之前,可以省略声明。,float add (float x, float y) float z; z=x+y; return (z); main() float a, b; scanf(“ %f, %f, “ ,共 81页 第 33 页,如果已在所有函数定义之前,在文件的开头, 在函数的外部已说明了函数类型,则在各个主

18、 调函数中不必对所调用的函数再作声明。,char letter( char,char); float f(float,float ); int i(float,float); main( ) . char letter (char c1,char c2) float f(float x,float y) int i(float,float) ,此处不必说明,共 81页 第 34 页,# include “stdio.h” /*调用输入输出函数*/ # include “math.h” /*调用数学函数*/ # include “string.h” /*调用字符,字符串函数*/ # includ

19、e “graphics.h” /*调用图形函数*/ 用户也可建立自己的库函数,这是高级应用的内容。,5. 库函数及调用 库函数:由人们根据需要编制并提供给用户使用的一些基 本函数,在用户定义的函数中常常调用这些函数。 方法:在文件的开头用#include 命令将需要的库函数包含到 文件中。,共 81页 第 35 页,7.2 数组作函数参数,数组元素可以作函数的实参 数组名可以作函数的实参和形参 多维数组可以作函数参数 7.2.1. 数组元素作函数实参 由于表达式可以做实参,数组元素可以作为表达式的组成部分,因此,数组元素可以做函数的实参,与变量一样,是单向传递,即“值传送”方式。 例如: in

20、t a10; x=power(a9,5);,共 81页 第 36 页,7.2.2数组名作函数的参数,可以用数组名作函数参数,此时实参和形参都用数组名。 由于数组名代表的就是数组在内存中存放区域的首地址。把数组名作为函数参数来实现大量数据的传递是一个非常好的数据传递方法。,这种传递方式是“地址传递”,共 81页 第 37 页,有两种形式: 函数值类型说明符 函数名(类型说明符 数组名 ,) 函数体 函数值类型说明符 函数名(数组名,) 类型说明符 数组名 ; 函数体 ,1. 一维数组作函数参数,2. 数组作函数形参的函数调用方式 函数名(数组名,),共 81页 第 38 页,说明: 在主调函数和

21、被调用函数中分别定义数组。 实参数组和形参数组类型要一致。 实参数组和形参数组大小可以不一致,形参数组可以不指定大小。 (这里指一维数组)。 函数调用时,形参数组将获得实参数组的起始地址。,共 81页 第 39 页,例: 编写函数,求n个数组元素的算术平均值。 double average(int a , int n) int i; double s=0; for(i=0; in; i+) s=s+ai; return s/n; ,主函数调用如何编写?,main() int b3=1,2,3; double s; s=average(b,3); printf(“%fn”,s); ,形参数组不指

22、定大小,数组名后跟一个空方括号,a获得b的起始地址,数组名做函数是“地址传递”。也就是把实参数组的起始地址传递给形参数组,这样二者共占一段内存单元。因此,形参数组各元素的值如果发生变化会使实参数组各元素的值发生同样的变化。 例:阅读下列程序,指出输出结果。 main( ) void swap( ); /*函数声明*/ int b2=10,2; swap(b); printf(“b0=%d, b1=%dn”, b0, b1); ,void swap( int a ) int t; t=a0; a0=a1; a1=t; ,共 81页 第 41 页,函数开始调用之前,函数开始调用,实参数组b将起始地

23、址传递给形参数组a,二者共占一段内存单元,swap函数执行过程中,a0与a1的值交换,函数调用结束后,共 81页 第 42 页,例:编写一个函数. 功能:在n个整数中,找出数值最大的数。 给定10个整型数,找出其中数值最大的数。,共 81页 第 43 页,例:用选择法对数组中10个整数按由小到大排序.,方法:,写一个函数sort(array, n) :对数组元素按由小到大排序。,写主函数 :输入array数组,调用 sort 函数,输出排序后的array数组。,void sort (int array , int n) int i, j, t; for (i=0; in-1; i+) for

24、(j=i+1; jn; j+) if (arrayjarrayi) t=arrayj; arrayj=arrayi; arrayi=t; ,共 81页 第 44 页,main ( ) int a10, i; printf(“enter array: n”); for (i=0; i10; i+) scanf (“%d”, ,由于地址传递,实参数组 a 改变,数组名做参数的好处:,由于只需复制一个地址值,而无须复制全部需要处 理的数据,因此节约存储空间并提高效率。,由于主调函数和被调函数是在相同的内存区域上对 数据进行操作,因此可以实现数据的同步更新。,共 81页 第 45 页,有两种形式 (形

25、式基本同一维) 函数值类型说明符 函数名(类型说明符 数组名 正整型常量表达式 , ) 函数体 函数值类型说明符 函数名(数组名,) 类型说明符 数组名 正整型常量表达式; 函数体 ,7.2.3 二维数组作函数参数,“行”可以不确定,“列”必须确定!,共 81页 第 46 页,说明: 形参数组定义时可以指定每一维的大小,也可以省略第一维的大小,不允许省略第二维以及其他高维的大小. 例如 : int array 310; 或 int array 10; 是一样的! 但 int array 3 ; 和int array ;是错误的!,实参数组可以大于形参数组。(行可以不同,列必须相同) 例如:实参

26、数组定义为:int array 510; 形参数组定义为:int array 310; 这时形参数组只取实参数组的一部分,其余部分不起作用。,共 81页 第 47 页,例:阅读程序,指出运行结果。 void add1(int a 3 ,int n) int i; for(i=0;in;i+) +aii; main() int x33=0,1,2,3,4,5,6,7,8,i; add1(x,3); for(i=0;i3;i+) printf(“%d “,xii); printf(“n“); ,程序运行结果为:1 5 9,共 81页 第 48 页,例:写函数打印n行10列二维数组,其中n是任意整数

27、。 void print_array(int a 10, int n) int i, j; for(i=0;in; i+) for(j=0;j10;j+) printf(“%3d”, aij); printf(“n”); ,例:写函数交换任意一个n*10的二维数组的i,j两行 void exchange(int a 10, int i,int j) int k, t; for(k=0;k10;k+) t=aik; aik=ajk; ajk=t; ,共 81页 第 49 页,7.3 函数的嵌套调用和递归调用,7.3.1 函数的嵌套调用 嵌套定义:在定义一个函数时,该函数体内包含另一个函数的定义。

28、 嵌套调用:在调用一个函数的过程中,又调用另一个函数。 C语言不允许嵌套定义,但可以嵌套调用。在调用一个函数的过程中,又调用另一个函数。,共 81页 第 50 页,函数的嵌套调用,main函数 调用函数 A; ,函数 A 调用函数 B; ,函数 B ,调用,调用,返回,返回,共 81页 第 51 页,例:阅读程序,指出运行结果。,main( ) int a=0,b=0,b1(int,int); printf(“b1=%d f1=%dn“,b1(a,b),f1( ); b1(int d,int e) int f1( ),f; d=5; e=10; f=f1( )+d+e; return f; f

29、1( ) int c,i=1; c=15; while(i=3) c*=i; i+; return c; ,程序执行结果: b1=105 f1=90,f1返回的是整型可以省略声明,这个说明也可以省略,函数声明。也可写成原型: b1(int d,int e) 此例b1返回的是整型也可以不说明,共 81页 第 52 页,7.3.2 函数的递归调用,1. 递归的概念:在调用一个函数的过程中直接或间接地调用该函数本身。,f 函数,调用 f函数,直接递归调用 int f(x) int x; int y,z; z=f(y); return (2*z); ,共 81页 第 53 页,int f1(x) in

30、t x; int y,z; z=f2( y); return (2*z); ,int f2(t) int t; int a,c; c=f1(a); return (3+c); ,间接递归调用,共 81页 第 54 页,递归函数的执行过程: 递归调用:记住本次现场,递归调用。 终了调用:返回上次调用现场。 特点 是无终止的递归调用,因此,应该给定一个限制递归次数的条件。,共 81页 第 55 页,int f(int x) int y; if(x=0|x=1)return(3); y=x*x-f(x-2); return y; main() int z; z=f(3);printf(“%dn”,z

31、); ,A) 0 B) 9 C) 6 D) 8,例:阅有以下程序段,运行后的结果是:,举例:编写计算 n! 的程序。 n*(n-1)! 当 n1,long int fact(int n) long int f; if(n=0|n=1) f=1; else f=n*fact(n-1); return f; main( ) long int red;int n; scanf(“%d“, ,假如求 5! , 则程序执 行结果为:red =120,1 当 n=0,n=1,共 81页 第 57 页,第一次调用,第二次调用,第三次调用,第四次调用,第五次调用,返回,返回,返回,返回,返回,共 81页 第

32、58 页,变量的数据类型,char 型 int 型 float 型 double 型,总结:数据类型决定为变量分配的内存单元的长度,数据的存放 形式。(从程序设计角度,决定了可以表示的数的范围),问题:1. 何时为变量分配内存单元? 2. 变量位于内存的什么位置? 3. 变量的有效作用范围?,7.4 变量的作用域和存储方法,共 81页 第 59 页,变量的作用域和生存期 变量的作用域 指一个变量在程序中的有效范围。 C语言规定:凡是在函数内定义的变量,它的作用域仅仅是包含这个变量定义的复合语句;而在函数体外定义的变量,它的作用域是从定义点到文件尾。 变量的生存期 指程序在执行期间,变量存在的时

33、间间隔,即从给变量分配内存,至所分配内存被系统收回的那段时间。 C语言规定:凡是出现在静态数据区的变量,生存期都是从程序开始执行到程序结束;而出现在静态区之外的变量,生存期仅仅是从函数开始执行到函数执行结束这段时间。,共 81页 第 60 页,1. 局部变量(内部变量) 定义:在函数内部定义的变量,只能在本函数内部使用,称为局部量。,7.4.1局部变量和全局变量(从变量的作用域分),如:float f1(int a) int b,c; char f2(int x,int y) int a,b; main ( ) int m,n; . ,共 81页 第 61 页,主函数 main 定义的变量只在

34、主函数中有效,主函数不能使用其它函数定义的变量。 不同函数可以使用相同名字的变量,它们在内存中占不同的单元,互不影响。(如,前例f1和f2中的a,b变量) 形式参数也是局部变量。 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效。,关于局部变量几点说明:,如:main() int a,b; /*a,b在整个main函数内有效*/ int c; /*c仅在本复合语句内有效*/ c=a+b; . ,共 81页 第 62 页,2. 全局变量 程序中,在函数之外定义的变量称为外部变量,即全局变量。全局变量可以为本文件中的其他函数所共用,但是,它的有效范围是从定义变量的位置开始到源

35、文件的结束。,如:int p=1,q=5; float f1(int a) int b,c; char c1,c2; char f2(int x,int y) int a,b; main ( ) int m,n; . ,共 81页 第 63 页,从定义变量的位置开始到本文件结束,这段程序中的函数可直接使用全局变量。(注意全局变量的有效范围) 如果在同一源文件中,全局变量和局部变量同名,则在局部变量的作用范围内,全局变量不起作用。,关于全局部变量几点说明:,共 81页 第 64 页,例如: #include “stdio.h” int a=7,b=10; main( ) int a=5,c; c

36、=a+b; printf(“c=%dn”,c); ,运行结果:c=15,全局量的a没有起作用,共 81页 第 65 页,使用全局变量的优点: 函数间数据联系:同一文件中的一些函数引用全局 变量,当某个函数中改变了全局变量的值,其它函数中的全局变量值也随之改变。 函数可以得到多个返回值。 缺点: 全局 变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。 降低函数的通用性,因为函数在执行时要依赖其使用的全局变量。(对函数的移植带来不便) 使用过多,降低程序的清晰性,难以判别全局变量的值。,提示:全局变量应尽可能少用。,共 81页 第 66 页,两种: 静态存储方式:程序运行期间

37、分配固定存储空间的方式。 动态存储方式:程序运行期间根据需要进行动态的分配存储空间的方式。,7.4.2 变量的存储方法,运行期间的C程序占用的内存由3部分构成 :,共 81页 第 67 页,变量存贮类型有四种: 1.自动变量(auto) 2.静态变量(static) 3.寄存器变量(register) 4.外部变量( extern),局部变量,共 81页 第 68 页,1.局部变量的存储方法 (1)自动变量 (auto) 动态分配存储空间的变量。如:函数中的局部变量、函数的形参、复合语句中的局部变量,称为自动变量,用关键字auto作为存储类型说明。 如:int f(int a) auto in

38、t b,c=3; ,自动变量被分配在动态存储区,用前分配,用后释放。,实际上不加特殊声明(static)的局部变量都是自动变量,因此在定义自动变量时,关键字可以省略。,int f(int a) int b,c=3; ,写成为:,共 81页 第 69 页,(2)用(static)声明局部变量 静态存储方式,整个程序运行期间都不释放。 定义形式:在变量名前面加 关键字static static 类型说明符 变量名; 编译时赋初值,每次调用时不赋初值,只保留调用结束时变量的值。 如果局部静态变量不赋初值,编译时自动赋0,而自动变量不赋初值,其值不确定。 局部静态变量只允许所在函数引用,其它函数不能引

39、用。,共 81页 第 70 页,例如: f(int a) int b=0; static int c=3; b=b+1; c=c+1; return( a+b+c); main( ) int a=2 , i; for(i=0; i3; i+) printf(“%d ”,f(a); ,运行结果为: 7 8 9,第一次调用开始,第一次调用结束,第二次调用开始,0,b,3,4,4,1,0,c,共 81页 第 71 页,(3)寄存器变量 (register) 定义:直接放置在运算器的寄存器中的变量称为寄存器变量 说明方式:在变量名前面加 关键字register register 类型说明符 变量名;

40、只有局部自动变量和形式参数才可以声明为寄存器变量,因为register变量在函数调用结束时必须释放。,如:int fac(int n) register int i,f=1; for ( i=1;i=n;i+) f=f+i; return(f); ,注意:局部静态变量不能声明为寄存器变量,共 81页 第 72 页,2. 全局变量的存储方法 (1)外部全局变量 在多个源程序文件的情况下,如果在文件B中要引用文件A中所定义的全局变量,则应该在文件B中对所要引用的变量,用extern说明。例如:,prog1.c的内容如下: int a; main( ) x=6; f1( ); void f1( )

41、a+=2; printf(“a=%dn“, a); f2( ); ,prog2.c的内容为: extern int a; void f2( ) a+; printf(“a=%dn“, a); ,对文件prog1.c中全局变量a的声明,共 81页 第 73 页,(2)静态全局变量 若在一个文件中定义的全局变量仅限于本文件引用,而不能被其它文件访问,则可以定义为静态全局变量。 例如: static int x;,例如:file1.c file2.c static int a ; extern int a; main() fun(int n); static int a只能用于file1.c ,虽然

42、file2.c中将 同名变量 int a说明为extern,但仍无法使用file1.c 中的 a变量。,共 81页 第 74 页,7.5 内部函数和外部函数,1 . 内部函数(静态函数) 定义:如果一个函数只能被本文件中其它函数调用,称为内部函数。 定义格式: static 类型标识符 函数名(形参表)函数体 例如:static int fun(a, b) 作用:函数的作用域限于所在文件,不同文件中同名函数互不干扰,便于程序的格式化。,共 81页 第 75 页,2. 外部函数 定义:如果一个函数允许被其它文件调用,称为外部函数。 定义格式: extern 类型标识符 函数名(形参表)函数体 例

43、如:extern int fun(int a, int b) 或 int fun(int a, int b) 通常不加 static 标识符的函数都是外部函数(我们前面所有函数)。,共 81页 第 76 页,3.标号的生存期及作用域 生存期 在C语言中,由于函数的生存期是全程的,即从程序开始至程序结束,标号是函数的一部分,标号的生存期自然是全程的。 作用域 C语言规定,标号的作用域仅为定义标号的函数,即不允许用goto语句从一个函数转向另一个函数。,共 81页 第 77 页,函数间的数据传递 三种传递方式,返回值 参数 全局变量,共 81页 第 78 页,函数的返回值,通过 return 语句

44、返回。 return 语句只能把一个返值传递给调用函数。 返回值的类型为定义的函数类型,若 return 语句中表达式类型与函数类型不一致,则转换为函数类型。 返回值可以是数值,也可以是地址。当返值是地址时,应该用指针接受它。 无返回值的函数,定义为 void 类型。,共 81页 第 79 页,函数间的参数传递,在函数被调用时才分配形参的存储单元。 实参可以是常量、变量或表达式。 实参类型必须与形参相符。 传递时是传递参数值,即单向传递。 使用地址作为参数,可以返回函数处理结果。 数组作为参数时的情况。 数组元素作实参,与单个变量一样。 数组名作参数,传送的是数组首地址。,共 81页 第 80

45、 页,使用全局变量传递数据,在所有函数之外说明的变量是全局变量,它在所有函数中都是可见的。 利用全局变量的这个特性,可以在函数间传递数据,共 81页 第 81 页,作业 第七章:练习 二、三 编程题: 1、编写计算一维n个数组元素中下标为偶数的各元素之积的函数。 功能:计算一维数组a中10个元素下标为偶数的各元素的乘积。 2、编写计算一维数组排序的函数(由大到小) 功能:将一维数组a由大到小排序。,共 81页 第 82 页,第十一周:作业 第七章:练习一、四 编程题: 1、编写计算n*4矩阵中最大元素的函数。 功能:求3*4矩阵中最大的元素 2、编写cmX4=amX4+bmx4的函数. 功能:求z3X4=x3X4+y3x4。,

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1