C语言课件第八章

上传人:re****.1 文档编号:579293859 上传时间:2024-08-26 格式:PPT 页数:75 大小:1,023.03KB
返回 下载 相关 举报
C语言课件第八章_第1页
第1页 / 共75页
C语言课件第八章_第2页
第2页 / 共75页
C语言课件第八章_第3页
第3页 / 共75页
C语言课件第八章_第4页
第4页 / 共75页
C语言课件第八章_第5页
第5页 / 共75页
点击查看更多>>
资源描述

《C语言课件第八章》由会员分享,可在线阅读,更多相关《C语言课件第八章(75页珍藏版)》请在金锄头文库上搜索。

1、教学目与要求:教学目与要求:明确明确C程序由一个或多个函数构成,掌握函数的定义方法,程序由一个或多个函数构成,掌握函数的定义方法,熟悉函数的传值调用,嵌套调用,递归调用的执行过程;熟悉函数的传值调用,嵌套调用,递归调用的执行过程;掌握变量的类型,作用域,生存期等概念,正确使用动态掌握变量的类型,作用域,生存期等概念,正确使用动态变量,静态变量。变量,静态变量。教学内容:教学内容:概述;函数定义的一般形式;函数的参数和函数的值;函概述;函数定义的一般形式;函数的参数和函数的值;函数的调用;函数的嵌套调用;函数的递归调用;数组作为数的调用;函数的嵌套调用;函数的递归调用;数组作为函数参数;局部变量

2、和全局变量;变量的存储类别;内部函数参数;局部变量和全局变量;变量的存储类别;内部函数和外部函数;如何运行一个多文件的程序。函数和外部函数;如何运行一个多文件的程序。教学重点与难点:教学重点与难点:重点是函数的定义和调用,变量的作用域和生存期难点是重点是函数的定义和调用,变量的作用域和生存期难点是函数的嵌套调用与递归调用。函数的嵌套调用与递归调用。 Ch8 函数函数 特点:特点:各模块相对独立、功能单一、结构清晰、接口简单各模块相对独立、功能单一、结构清晰、接口简单控制了程序设计的复杂性控制了程序设计的复杂性缩短开发周期缩短开发周期避免程序开发的重复劳动避免程序开发的重复劳动易于维护和功能扩充

3、易于维护和功能扩充l 8.1 概述概述uC是模块化程序设计语言是模块化程序设计语言 基本思想:将一个大的程序按基本思想:将一个大的程序按功能功能分割成一些分割成一些小模块小模块开发方法开发方法: 自上向下,逐步细化自上向下,逐步细化&一个一个C C程序由一个程序由一个 或多个程序模块组成或多个程序模块组成, ,每个每个 程序模块作为一个源程序文件程序模块作为一个源程序文件&C C是是函数式函数式语言语言, ,一个源程序文件由一个或多个函数一个源程序文件由一个或多个函数 以及其他有关内容组成以及其他有关内容组成. .&一个一个C C程序程序必须有且只能有一个名为必须有且只能有一个名为mainma

4、in的主函数的主函数&C程序的执行总是程序的执行总是从从mainmain函数开始,函数开始,mainmain函数结束时函数结束时结束结束&函数函数不能嵌套定义不能嵌套定义, ,可以可以嵌套嵌套调用调用, ,但不能调用但不能调用mainmain函数函数. .&所有子函数都是所有子函数都是平行的,平行的,任何函数任何函数都不属于都不属于其他函数其他函数C是模块化程序设计语言是模块化程序设计语言C C程序结构程序结构函数分类函数分类从从用户角度用户角度标准函数(库函数):由系统提供标准函数(库函数):由系统提供用户自定义函数用户自定义函数从从函数形式函数形式无参函数无参函数有参函数有参函数使用使用库

5、函数库函数应注意:应注意:1、函数、函数功能功能2、函数参数的、函数参数的数目和顺序数目和顺序,及各参数意义和,及各参数意义和类型类型3、函数返回值意义和类型、函数返回值意义和类型4、需要使用的包含文件、需要使用的包含文件8.2 函数定义的一般格式合法标识符合法标识符函数返回值类函数返回值类型型缺省缺省int型型无返回值无返回值void函数体函数体类型标识符类型标识符 函数名函数名( )说明部分说明部分语句部分语句部分例例 空函数空函数 dummy( ) 函数体为空函数体为空例例 无参函数无参函数 printstar( ) printf(“*n”); 或或 printstar(void ) p

6、rintf(“*n”); 8.2.18.2.1无参函数无参函数定义的一般格式定义的一般格式8.2.2 有参函数定义有参函数定义 的一般格式的一般格式合法标识符合法标识符函数返回值类函数返回值类型型缺省缺省int型型无返回值无返回值void函数体函数体类型标识符类型标识符 函数名函数名(形参类型说明表形参类型说明表)说明部分说明部分语句部分语句部分例例 有参函数有参函数 int max(int x,int y) int z; z=xy?x:y; return(z); 例例 有参函数号有参函数号 int max(int x, y) int z; z=xy?x:y; return(z); 函数类型函

7、数类型 函数名(形参表)函数名(形参表)形参类型说明形参类型说明说明部分说明部分语句部分语句部分传统风格传统风格: :例例 有参函数(传统风格)有参函数(传统风格) int max(x,y) int x,y; int z; z=xy?x:y; return(z); 8.2.3 空函数空函数void 函数名函数名( ) 作用作用: 在程序设计中往往根据需要确定若干模块在程序设计中往往根据需要确定若干模块,分别由一些分别由一些 函数实现函数实现,而在第一阶段中设计最基本的模块而在第一阶段中设计最基本的模块,其他一些其他一些 次要功能或锦上添花的功能则在以后需要时陆续补上次要功能或锦上添花的功能则在

8、以后需要时陆续补上, 在编写程序的开始阶段在编写程序的开始阶段,可以在将来要扩充的地方写一可以在将来要扩充的地方写一 个空函数个空函数.8.3.1 形参与实参形参与实参形式参数:定义函数时函数名后面括号中的变量名形式参数:定义函数时函数名后面括号中的变量名实际参数:调用函数时函数名后面括号中的参数实际参数:调用函数时函数名后面括号中的参数例例 比较两个数并输出大者比较两个数并输出大者max(int x, int y) int z; z=xy?x:y; return(z);main() int a,b,c; scanf(%d,%d,&a,&b); c=max(a,b); printf(Max i

9、s %d,c);8.3 函数参数和函数的值函数参数和函数的值说明:说明:形参在函数被调用前不占内存形参在函数被调用前不占内存;函函数调用时为形参分配内存;调用结数调用时为形参分配内存;调用结束,内存释放束,内存释放实参可为常量实参可为常量,变量或表达式变量或表达式,但必但必须有确定的值须有确定的值,调用时实参的值传给调用时实参的值传给形参形参.形参必须指定类型形参必须指定类型形参与实参形参与实参类型一致,个数相同类型一致,个数相同若形参与实参类型不一致,自动若形参与实参类型不一致,自动按形参类型转换按形参类型转换函数调用函数调用转换转换实参到形参是单向的值传递反过实参到形参是单向的值传递反过来

10、不行来不行.例例 计算计算x的立方的立方#include float cube(float x) return(x*x*x);main() float a, product; printf(Please input value of a:); scanf(%f,&a); product=cube(a); printf(”Cube of %.4f is %.4fn,a,product);xaproduct1.21.21.728返回语句返回语句形式:形式: return(表达式表达式);或或 return 表达式表达式;或或 return;功能功能:使程序控制从:使程序控制从被调用函数被调用函数返

11、回到返回到调用函数调用函数中,中,同时把返同时把返回回值带给调用函数值带给调用函数说明:说明:函数中可有多个函数中可有多个return语句语句若无若无return语句,遇语句,遇时,自动返回调用函数时,自动返回调用函数,返回的是一返回的是一个不确定的值个不确定的值若函数类型与若函数类型与return语句中表达式值的语句中表达式值的类型不一致类型不一致,按前,按前者为准,自动转换者为准,自动转换-函数调用转换函数调用转换void型函数型函数没有返回值没有返回值例例 无返回值函数无返回值函数 void swap(int x,int y ) int temp; temp=x; x=y; y=temp

12、; 8.3.2 函数的返回值函数的返回值 printstar() printf(*);main() int a; a=printstar(); printf(%d,a);例例 : 下列函数的不同。下列函数的不同。void printstar() printf(*);main() int a; a=printstar(); printf(%d,a);*10 编译错误编译错误not an allowed type例例: 函数返回值类型转换函数返回值类型转换max(float x, float y) float z; z=xy?x:y; return(z);main() float a,b; int

13、 c; scanf(%f%f,&a,&b); c=max(a,b); printf(Max is %dn,c);教学目与要求:教学目与要求:熟悉函数的传值调用熟悉函数的传值调用嵌套调用嵌套调用递归调用的执行过程;递归调用的执行过程;教学内容:教学内容:函数的嵌套调用;函数的嵌套调用;函数的递归调用;函数的递归调用;数组作为函数参数;数组作为函数参数;教学重点与难点:教学重点与难点:函数的嵌套调用与递归调用。函数的嵌套调用与递归调用。 Ch8 函数函数(2)8.4 8.4 函数的调用函数的调用8.4.1调用的一般形式调用的一般形式 函数名函数名(实参表列实参表列);说明:说明:实参与形参实参与形

14、参个数相等,类型一致,按顺序一一对应个数相等,类型一致,按顺序一一对应实参表求值顺序,因系统而定(实参表求值顺序,因系统而定(Turbo C 自右向左自右向左)8.4.2 调用方式调用方式函数语句:函数语句: 例例 printstar(); printf(“Hello,World!n”);函数表达式:函数表达式: 例例 m=max(a,b)*2;函数参数:函数参数: 例例 printf(“%d”,max(a,b); m=max(a,max(b,c);int f(int a, int b) int c; if(ab) c=1; else if(a=b) c=0; else c=-1; retur

15、n(c);void main() int i=2,p; p=f(i,+i); printf(%d,p);例例 参数求值顺序参数求值顺序int f(int a, int b) int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return(c);void main() int i=2,p; p=f(i, i+); printf(%d,p);运行结果:运行结果:0TC运行结果:运行结果:1VC : 0对被调用函数要求:对被调用函数要求:必须是必须是已存在已存在的函数的函数库函数应该使用库函数应该使用 #include 用户自定义函数或者在调用前面,或者

16、先有用户自定义函数或者在调用前面,或者先有函数类型说明函数类型说明告诉编译系统告诉编译系统函数类型、参数个数及类型,以便检验函数类型、参数个数及类型,以便检验函数定义函数定义与与函数声明函数声明不同不同函数定义函数定义是指函数功能的确立,包括函数名、值、形参以及是指函数功能的确立,包括函数名、值、形参以及函数体,是一个完整的、独立的函数单位。函数体,是一个完整的、独立的函数单位。函数声明函数声明告诉编译系统告诉编译系统函数类型、参数个数及类型,以便检函数类型、参数个数及类型,以便检验验8.4.3 对被调用函数的声明和函数原型对被调用函数的声明和函数原型例例 函数函数声声明举例明举例float

17、add(float x, float y) float z; z=x+y; return(z);void main() float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);被调函数出现在主调函数被调函数出现在主调函数之前,不必函数之前,不必函数声声明明/*ch8-4.c*/void main() float add(float x,float y); float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);float add(float x,

18、float y) float z; z=x+y; return(z);void main() int a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);max(int x, int y) int z; z=xy?x:y; return(z);int型函数可不作函数说型函数可不作函数说声声明明(Borland C+不行)不行)8.4.3 对被调用函数的声明和函数原型对被调用函数的声明和函数原型函数的声明简称函数原型函数的声明简称函数原型.一般情况下,函数的一般情况下,函数的声明与函数定声明与函数定义的第一行(函数首部

19、)基本相同,但差一个分号义的第一行(函数首部)基本相同,但差一个分号,因此,可以简因此,可以简单地照写已经定义的函数的首部,再加一个分号,就成了声明。单地照写已经定义的函数的首部,再加一个分号,就成了声明。函数原型的形式函数原型的形式 (1) 函数类型函数类型 函数名函数名(形参类型形参类型1,形参类型,形参类型2,.形参类型形参类型n); (2) 函数类型函数类型 函数名函数名(形参类型形参类型1 参数名参数名1,形参类型形参类型2 参数名参数名2,., 形参类型形参类型n 参数名参数名n); 编译系统不检查参数名,参数名是什么无所谓编译系统不检查参数名,参数名是什么无所谓函数说明位置:函数

20、说明位置:程序的数据说明部分(函数内或外程序的数据说明部分(函数内或外)下列情况下,可不作函数说明下列情况下,可不作函数说明被调用函数定义出现在主调函数之前被调用函数定义出现在主调函数之前如果已经在头文件的开头(在所有函数之前)已经对本文如果已经在头文件的开头(在所有函数之前)已经对本文件中所调用的函数进行了声明,则在各函数中不必再说明。件中所调用的函数进行了声明,则在各函数中不必再说明。若函数返值是若函数返值是char或或int型型,系统自动按,系统自动按int型处理型处理int sum(int a, int b) a=a+b; b=a+b; return(a);void main() in

21、t a=1,b=3,c; c=sum(a,b); printf(%d,%d,%d,a,b,c);例例 读程序写出程序结果。读程序写出程序结果。1,3,4void main() float add(float a,float b); float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);float add(float x, float y) float z; z=x+y; return(z);8.5 8.5 函数的嵌套调用函数的嵌套调用main( )调用函数调用函数a结束结束a函数函数b函数函数调用函数调用函数bu嵌套调

22、用嵌套调用C规定:规定:函数定义不可嵌套函数定义不可嵌套,但,但可以嵌套调用可以嵌套调用函数函数,即在调用一个函数的过程中又调用另一个函数。即在调用一个函数的过程中又调用另一个函数。例例 求三个数中最大数和最小数的差值求三个数中最大数和最小数的差值#include int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z);void main() int a,b,c,d; scanf(%d%d%d,&a,&b,&c); d=dif(a,b,c); printf(Max-Min=%dn,d)

23、; int dif(int x,int y,int z) return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); int min(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); main( )调用函数调用函数dif输出输出结束结束dif函数函数max函数函数调用函数调用函数max调用函数调用函数minmin函数函数float fac(int k) float t=1; int i; for (i=2;i=k;i+)

24、t*=i; return t; void main() float c; int m,n; scanf(“%d,%d”,&m,&n); c=fac(n)/(fac(m)*fac(n-m); printf(“%f”,c); 例例 求求分析:分析:重复三次求阶乘运算,只是每次的值不同。将求阶乘重复三次求阶乘运算,只是每次的值不同。将求阶乘的过程编成一个函数,以不同的参数值来调用函数。的过程编成一个函数,以不同的参数值来调用函数。说明说明:C编译系统对递归函数的自调用编译系统对递归函数的自调用次数没有限制次数没有限制每调用函数一次,在每调用函数一次,在内存堆栈区分配空间内存堆栈区分配空间,用于,用于

25、存放函数变存放函数变量、返回值量、返回值等信息,所以递归次数过多,可能引起堆栈溢出等信息,所以递归次数过多,可能引起堆栈溢出l 8.68.6 函数的递归调用函数的递归调用定义:函数定义:函数直接或间接的调用自身直接或间接的调用自身叫函数的递归调用叫函数的递归调用f( )调调f调调f2调调f1f1( )f2( )int f(int x) int y,z; z=f(y); . return(2*z);int f1(int x) int y,z; z=f2(y); . return(2*z);int f2(int t) int a,c; c=f1(a); . return(3+c);此两种递归都此两

26、种递归都无法结束无法结束,应,应有有某种条件某种条件控控制递归调用结制递归调用结束。束。例例 8.8int age(int n) int c; if(n=1) c=10; else c=age(n-1)+2; return(c);void main() printf(“%dn”,age(5);age(5)= age(4)+1age(4)= age(3)+1age(3)= age(2)+1age(2)= age(1)+1age(1)= 10age(2)= 12age(3)= 14age(4)= 16age(5)= 18例例 8.8 求求n的阶乘的阶乘/*ch8_8.c*/#include flo

27、at fac(int n) float f; if(n0) printf(n0,data error!); else if(n=0|n=1) f=1; else f=fac(n-1)*n; return(f);void main() int n; float y; printf(Input a integer number:); scanf(%d,&n); y=fac(n); printf(%d! =%15.0f,n,y);递归调用的实现递归调用的实现主程序主程序(1)输出输出f(4); 4 f (4);(1)n=4top(2) s=4*f(3)n3 f (3);(2)n=3 (1)n=4 t

28、op(3) s=3*f(2)n2 f (2);(3)n=2 (2)n=3 (1)n=4 top(4)s=2*f(1)n1(4)n=1 (3)n=2 (2)n=3 (1)n=4 tops s=3*2*1;(2) 3(1) 4top s=2*1(3) 2(2) 3(1) 4top s=4*3*2*1 (1 ) 4top返回返回(3) 2(2) 3(1) 4top(4) 1结束结束输出输出24例例:用数组求用数组求Fibonacci数列前数列前20个数个数long int fac(int n) long int f; if (n=1|n=2) f=1; else f=fac(n-1)+fac(n-2

29、); return f; void main() int i; for(i=1;i%cn,getone,putone); void hanoi(int n,char one,char two,char three) if(n=1) move(one,three); else hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); main() int m; printf(Input the number of disks:); scanf(%d,&m); printf(The steps to moving %3

30、d disks:n,m); hanoi(m,A,B,C);ABC从上面分析可以看出,当n大于等于2时,移动的过程可分解为三个步骤:第一步 把A上的n-1个圆盘移到B上;第二步 把A上的一个圆盘移到C上;第三步 把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。本题算法分析如下,设A上有n个盘子。如果n=1,则将圆盘从A直接移动到C。如果n=2,则:1.将A上的n-1(等于1)个圆盘移到B上;2.再将A上的一个圆盘移到C上;3.最后将B上的n-1(等于1)个圆盘移到C上。 如果n=3,则:A. 将A上的n-1(等于2,令其为n)个圆盘移到B(借助于C),步骤如下:(1)将A上的n-1(等

31、于1)个圆盘移到C上。(2)将A上的一个圆盘移到B。(3)将C上的n-1(等于1)个圆盘移到B。B. 将A上的一个圆盘移到C。C. 将B上的n-1(等于2,令其为n)个圆盘移到C(借助A),步骤如下:(1)将B上的n-1(等于1)个圆盘移到A。(2)将B上的一个盘子移到C。(3)将A上的n-1(等于1)个圆盘移到C。 到此,完成了三个圆盘的移动过程。【举例举例】将从键盘输入的字符序列逆置输出,用递归函数来实现。比如,从键盘上输入:比如,从键盘上输入:ABCD回车;算法将输出:回车;算法将输出:DCBA 。 void Reversed( ) char ch; ch=getchar(); if (

32、ch!=n) reversed(); if (ch!=n) printf(“%c”,ch);【举例举例】将从键盘输入的十进制正整数以二进制形式输出。用递归函数来实现。比如,从键盘上输入:比如,从键盘上输入:13回车;回车;算法将输出:算法将输出:1101 。 #include void main() int n; void bin(int); scanf(%d,&n); bin(n); void bin(int n) int r; r=n%2;n=n/2; if (n!=0) bin(n); printf(%d,r); 函数的递归调用小结函数的递归调用小结u用递归法编写函数的方法用递归法编写函

33、数的方法(1)分解分解:将原问题分解为若干小问题,其中:将原问题分解为若干小问题,其中至少至少有一个小问有一个小问题与原问题题与原问题性质完全相同性质完全相同;(2)找递归出口找递归出口(即(即递归结束条件递归结束条件):利用出口的结果逐步回):利用出口的结果逐步回代即可得到原问题的解。代即可得到原问题的解。u递归法的优点递归法的优点(1)编写的程序比较简洁清楚,增加了可读性;)编写的程序比较简洁清楚,增加了可读性;(2)有些问题)有些问题(如如Hanoi塔问题塔问题)用其他方法较难而用递归方法较用其他方法较难而用递归方法较易;易;(3)便于进行算法的复杂性分析。)便于进行算法的复杂性分析。u

34、递归法的缺点递归法的缺点:时间:时间和和空间空间的代价较大。的代价较大。注注:递归算法都可以转换为非递归算法。递归算法都可以转换为非递归算法。作业8.48.58.68.7教学目与要求:教学目与要求:理解数组作为函数参数;理解局部变量和全局变理解数组作为函数参数;理解局部变量和全局变量;了解变量的存储类别和内部函数和外部函数;量;了解变量的存储类别和内部函数和外部函数;知道如何运行一个多文件的程序。知道如何运行一个多文件的程序。教学内容:教学内容:数组作为函数参数;局部变量和全局变量;变量数组作为函数参数;局部变量和全局变量;变量的存储类别;内部函数和外部函数;如何运行一个的存储类别;内部函数和

35、外部函数;如何运行一个多文件的程序。多文件的程序。教学重点与难点:教学重点与难点:重点是数组作为函数参数,变量的作用域和生存重点是数组作为函数参数,变量的作用域和生存期是难点期是难点Ch8 函数函数(3)8.7 8.7 数组作为函数参数数组作为函数参数 函数参数传递方式函数参数传递方式值传递值传递方式方式方式:函数调用时方式:函数调用时,为形参分配单元为形参分配单元,并将实参的值并将实参的值复制复制到形参中;到形参中;调用结束,调用结束,形参单元被释放形参单元被释放,实参单元仍保留并维持,实参单元仍保留并维持原值原值特点:特点:形参与实参占用形参与实参占用不同不同的内存单元的内存单元单向单向传

36、递传递#include swap(int a,int b) int temp; temp=a; a=b; b=temp; void main() int x=7,y=11; swap(x,y); printf(x=%d,ty=%dn,x,y);地址传递地址传递方式:函数调用时,将数据的方式:函数调用时,将数据的存储地址存储地址作为参数传递给形参作为参数传递给形参特点:特点:形参与实参占用形参与实参占用同样同样的存储单元的存储单元“双向双向”传递传递实参和形参必须是实参和形参必须是地址地址常量或变量常量或变量8.7.18.7.1数组元素作函数实参数组元素作函数实参值传递值传递8.7 8.7 数组

37、作为函数参数数组作为函数参数int max (int x,int y) return (xy?x:y); void main() int a10,i,m; for (i=0;i10;i+) scanf(“%d”,&ai); m=a0; for(i=1;i10;i+) m=max(m,ai); printf(“max=%d”,m); 若函数的形参是数组,对应若函数的形参是数组,对应的实参必须是数组名或指针变量。的实参必须是数组名或指针变量。int max (int x10) int i,m=x0; for(i=1;i10;i+) if (mxi) m=xi; return m; void mai

38、n() int a10,i; for (i=0;i10;i+) scanf(“%d”,&ai); printf(“max=%d”,max(a);说明:说明:1.应该在主调函数和被调函数中分别定应该在主调函数和被调函数中分别定义数组义数组,不能只在一方定义不能只在一方定义.2.实参数组与形参数组的实参数组与形参数组的类型必须一致类型必须一致3.用数组名做参数时,传递的是数组的用数组名做参数时,传递的是数组的首地址,形参数组的大小不起作用首地址,形参数组的大小不起作用.4.形参数组形参数组可以不指定大小可以不指定大小,只用一个,只用一个方括号方括号,可另设一参数,传递数组元素可另设一参数,传递数组

39、元素的个数的个数5.数组做函数参数时,形参数组和实参数组做函数参数时,形参数组和实参数组数组共享同一内存单位共享同一内存单位例例 求求10个任意整数中的最大值个任意整数中的最大值8.7.2 数组名作函数参数数组名作函数参数地址传递地址传递int max (int x,int n) int i,m=x0; for(i=1;in;i+) if (mxi) m=xi; return m; void main() int a10,i; for (i=0;i10;i+) scanf(“%d”,&ai); printf(“max=%d”,max(a,10);例例 求学生的平均成绩求学生的平均成绩 #inc

40、lude float average(int stu10, int n); void main() int score10, i; float av; printf(Input 10 scores:n); for( i=0; i10; i+ ) scanf(%d, &scorei); av=average(score,10); printf(Average is:%.2f, av); float average(int stu10, int n) int i; float av,total=0; for( i=0; in; i+ ) total += stui; av = total/n; r

41、eturn av; 实参用数组名实参用数组名形参用数组定义, int stu .2109score562312.88stu数组排序数组排序-简单选择排序简单选择排序void sort(int array,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(arrayjarrayk) k=j; if(k!=i) t=arrayi; arrayi=arrayk; arrayk=t; void main() void sort(int array,int n); int a10,i; for(i=0;i10;i+)scanf(%

42、d,&ai); sort(a,10); for(i=0;i10;i+) printf(%d ,ai);0123456789a4968573299927137688arraykjjjkjkjjjjj949i=0例例 数组排序数组排序-简单选择排序简单选择排序void sort(int array,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(arrayjarrayk) k=j; if(k!=i) t=arrayi; arrayi=arrayk; arrayk=t; main() void sort(int array,

43、int n); int a10,i; for(i=0;i10;i+)scanf(%d,&ai); sort(a,10); for(i=0;i10;i+) printf(%d ,ai); printf(n);kjjkjkjjjjj0123456789a4968573299927137688array949kk1368i=1例例 数组元素与数组名数组元素与数组名 作函数参数比较作函数参数比较12a调用前调用前a0a112a调用调用a0a112xy21xy交换交换12a返回返回#include void swap2(int x,int y) int z; z=x; x=y; y=z;main() i

44、nt a2=1,2; swap2(a0,a1); printf(a0=%dna1=%dn,a0,a1);值传递值传递12a调用前调用前12ax调用调用21ax交换交换21a返回返回#include void swap2(int x) int z; z=x0; x0=x1; x1=z;main() int a2=1,2; swap2(a); printf(a0=%dna1=%dn,a0,a1);地址传递地址传递例例 数组元素与数组元素与 数组名数组名 作函数参数比较作函数参数比较8.7.18.7.1数组元素作函数实参数组元素作函数实参值传递值传递8.7 8.7 数组作为函数参数数组作为函数参数8

45、.7.2 8.7.2 一维数组作函数参数一维数组作函数参数地址传递地址传递int max (int x4) int i,j,m=x00; for(i=0;i3;i+) for(j=0;j4;j+) if (mxij) m=xij; return m; void main() int a34=1,3,5,7,9,2,4,6,8,10,15,13,17,5; printf(“max=%d”,max(a);1.多数数组元素可以作为函数的参数多数数组元素可以作为函数的参数2. 如果形参是多维数组,可以省略如果形参是多维数组,可以省略第一维第一维的大小,但不能省略其他维的大小。的大小,但不能省略其他维的

46、大小。8.7.3 8.7.3 多维数组与函数参数多维数组与函数参数int max(int x34)int max(int x4)int max(int x3) ()int max(int x) ()例:有一个例:有一个34的矩阵,求最大元的矩阵,求最大元素的值。素的值。例例 求二维数组中各行元素之和求二维数组中各行元素之和get_sum_row(int x3, int result ,int row, int col) int i,j; for(i=0;irow;i+) resulti=0;for(j=0;jcol;j+) resulti+=xij; main() int a23=3,6,9,

47、1,4,7; int sum_row2,row=2,col=3,i; get_sum_row(a,sum_row,row,col); for(i=0;irow;i+) printf(The sum of row%d=%dn,i+1,sum_rowi);314679asum_rowxresult18128.8.1 局部变量局部变量-内部变量内部变量定义:在定义:在函数内定义函数内定义,只在本函数内有效只在本函数内有效说明:说明:main中定义的变量只在中定义的变量只在main中有效中有效不同函数中同名变量,占不同内存单元不同函数中同名变量,占不同内存单元形参属于局部变量形参属于局部变量在一个函数

48、内在一个函数内,可定义在复合语句中有效的变量可定义在复合语句中有效的变量局部变量可用存储类型局部变量可用存储类型:auto register static (默认为默认为auto)float f1(int a) int b,c; .char f2(int x,int y) int i,j; main() int m,n; .a,b,c有效有效x,y,i,j有效有效m,n有效有效运行结果:运行结果:5 4 3 2 1例:复合语句中的变量例:复合语句中的变量#define N 5main() int i; int aN=1,2,3,4,5; for(i=0;iN/2;i+) int temp;te

49、mp=ai;ai=aN-i-1;aN-i-1=temp; for(i=0;iN;i+) printf(%d ,ai);例例 不同函数中同名变量不同函数中同名变量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);sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b);运行结果:运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=48.8 8.8 局部变量和全局变量局部变量和全局变量8.8.2 全

50、局变量全局变量-外部变量外部变量定义:在定义:在函数外定义函数外定义,可为,可为本文件所有函数共用本文件所有函数共用有效范围:从有效范围:从定义变量的位置开始定义变量的位置开始到本源文件结束,及有到本源文件结束,及有extern说明说明的其它源文件的其它源文件应尽量少使用全局变量,因为:应尽量少使用全局变量,因为:Y全局变量在程序全部执行过程中占用存储单元全局变量在程序全部执行过程中占用存储单元Y降低了函数的通用性、可靠性,可移植性降低了函数的通用性、可靠性,可移植性Y降低程序清晰性,容易出错降低程序清晰性,容易出错 定义定义 说明说明u次数:次数: 只能只能1次次 可说明多次可说明多次u位置

51、:位置: 所有函数之外所有函数之外 函数内或函数外函数内或函数外u分配内存:分配内存: 分配内存分配内存,可初始化可初始化 不分配内存不分配内存,不可初始化不可初始化外部变量说明:外部变量说明: extern 数据类型数据类型 变量表;变量表;外部变量定义与外部变量说明不同外部变量定义与外部变量说明不同若外部变量与局部变量同名,则外部变量被屏蔽若外部变量与局部变量同名,则外部变量被屏蔽外部变量可用存储类型外部变量可用存储类型:缺省缺省 或或 static全局变量增加了函数间数据联系的渠道全局变量增加了函数间数据联系的渠道,通过函数调用可通过函数调用可得到一个以上的值得到一个以上的值,一般将全局

52、变量名的第一个字母大写一般将全局变量名的第一个字母大写;#include float Max,Min;float average(float array, int n) int i; float sum=Max=Min=array0; for(i=1;imax) Max=arrayi; else if(arrayimin) Min=arrayi; sum+=arrayi; return(sum/n);main() int i; float ave,score10; /*Input */ ave=average(score,10); printf(max=%6.2fnmin=%6.2fn ave

53、rage=%6.2fn,Max,Min,ave);作作用用域域maxmin#include int a=3,b =5; /*a,b外部变量外部变量void main() int max(int a, int b); /*本行是函数声明本行是函数声明,a,b为形参为形参 int a=8; /*a为局部变量为局部变量 局部变量局部变量a作用范围作用范围 printf(“%dn”,max(a,b); 局部变量局部变量b作用范围作用范围int max(int a, int b) /*a,b为形参局部变量为形参局部变量 int c; c=ab?a:b; return(c);形参形参a,b作用范围作用范围

54、8.9 8.9 变量的存储类别变量的存储类别内存内存.main() int a; a=10; printf(“%d”,a);编译或函数调用时为其分配内存单元编译或函数调用时为其分配内存单元1020002001程序中使用变量名对内存操作程序中使用变量名对内存操作概述概述变量是对程序中变量是对程序中数据的存储空间的抽象。数据的存储空间的抽象。变量的变量的属性属性 数据类型:变量所持有的数据的性质(数据类型:变量所持有的数据的性质(操作操作属性属性) 存储属性存储属性 存储器类型:寄存器、静态存储区、存储器类型:寄存器、静态存储区、动态存储区动态存储区 作用域作用域:变量在程序中的作用范围:变量在程

55、序中的作用范围-局部变量与全局变量局部变量与全局变量 生存期生存期:变量占用内存单元的时间:变量占用内存单元的时间-静态存储与动态存储静态存储与动态存储8.9.1 动态变量与静态变量动态变量与静态变量存储方式存储方式静态存储静态存储:编译时为其分配的,程序运行期间占有该固定存:编译时为其分配的,程序运行期间占有该固定存储空间,直到程序运行结束。储空间,直到程序运行结束。动态存储动态存储:程序运行期间根据需要动态分配存储空间。:程序运行期间根据需要动态分配存储空间。内存用户区内存用户区程序区程序区静态存储区静态存储区动态存储区动态存储区全局变量、局部静态变量全局变量、局部静态变量形参变量形参变量

56、局部动态变量(局部动态变量(auto,register)函数调用现场保护和返回地址等函数调用现场保护和返回地址等生存期生存期静态变量静态变量:从从程序开始程序开始执行到程序结束执行到程序结束动态变量动态变量:从包含该变量定义的从包含该变量定义的函数开始执行函数开始执行至函数执行结束至函数执行结束8.9 8.9 变量的存储类别变量的存储类别8.9.2 auto -自动型自动型 函数中的局部变量函数中的局部变量(如不专门如不专门声明为声明为static存储类别存储类别)、函函数中的形参和在函数中定义数中的形参和在函数中定义的变量,的变量,在调用函数时系统在调用函数时系统会给它们分配存储空间,在会给

57、它们分配存储空间,在函数调用结束时就自动释放函数调用结束时就自动释放这些存储空间。这类局部变这些存储空间。这类局部变量称为自动变量。用关键字量称为自动变量。用关键字auto作存储类别的声明作存储类别的声明 ,可省略。int f(int a) auto int b,c=3; . . .8.9 8.9 变量的存储类别变量的存储类别8.9.3 static -静态型静态型 有时希望函数中的局部变量有时希望函数中的局部变量的值在函数调用结束后不消的值在函数调用结束后不消失而保留原值,即占有存储失而保留原值,即占有存储单元不释放,在下一次该函单元不释放,在下一次该函数调用时,该变量已有值,数调用时,该变

58、量已有值,是上一次函数调用结束时的是上一次函数调用结束时的值。这时就应该指定局部变值。这时就应该指定局部变量为量为“静态局部变量静态局部变量”,用,用关键字关键字static进行声明。进行声明。 #include void main()int f(int);int a=2,i; for(i=0;i3;i+) printf(%d ,f(a);int f(int a)auto int b=0; static int c=3; b=b+1; c=c+1; return(a+b+c);8.9 8.9 变量的存储类别变量的存储类别7 8 97 8 98.9.3 static -静态型的说明静态型的说明属

59、于静态存储类别属于静态存储类别静态局部变量在编译时赋初静态局部变量在编译时赋初值,即只赋初值一次值,即只赋初值一次不赋初值的话,则对静态局不赋初值的话,则对静态局部变量来说,编译时自动赋部变量来说,编译时自动赋初值初值0或空字符或空字符 在函数调用结束后仍然存在,在函数调用结束后仍然存在,但其他函数不能引用它但其他函数不能引用它#include void main() int i; int fac(int n); for(i=1;i=5;i+) printf(%d!=%dn,i,fac(i);int fac(int n)static int f=1; f=f*n; return(f);8.9

60、8.9 变量的存储类别变量的存储类别8.9.4 register -存器变量变量 为为了提高效率,了提高效率,C语语言允言允许许将局部将局部变变量得量得值值放在放在CPU中的寄存器中,中的寄存器中,这这种种变变量叫量叫“寄存器寄存器变变量量”,用关,用关键键字字register作声明。作声明。只有局部自动变量和形式参数可只有局部自动变量和形式参数可以作为寄存器变量;以作为寄存器变量;不能定义任意多个寄存器变量;不能定义任意多个寄存器变量;局部静态变量不能定义为寄存器局部静态变量不能定义为寄存器变量。变量。 #include int fac(int n)register int i,f=1; f

61、or(i=1;i=n;i+)f=f*i; return(f);void main()int i; for(i=0;i=5;i+)printf(%d!=%dn,i,fac(i);8.9 8.9 变量的存储类别变量的存储类别8.9.5用用extern声明外部变量声明外部变量 外部变量(即全局变量)是在函外部变量(即全局变量)是在函数的外部定义的,它的作用域数的外部定义的,它的作用域为从变量定义处开始,到本程为从变量定义处开始,到本程序文件的末尾。序文件的末尾。 1.在一个文件内声明外部变量在一个文件内声明外部变量#include void main()int max(int ,int); exte

62、rn A,B; printf(%dn,max(A,B);int A=13,B=-8;int max(int x,int y)int z; z=xy?x:y; return(z);8.9 8.9 变量的存储类别变量的存储类别8.9.5用用extern声明外部声明外部变量变量 2.在多个文件的程序中声明在多个文件的程序中声明外部变量外部变量#include int A;void main()int power(int);int b=3,c,d,m;printf(“Enter :n”);scanf(“%d%d”,&A,&m);C=A*b;printf(“%d*%dn”,A,b,c);d=power(

63、m);printf(“%d*%dn”,A,m,d);8.9 8.9 变量的存储类别变量的存储类别file1.cfile1.c#include extern A;int power(int n); int i,y=1;for(i=1;iy?x:y; return(z);main() extern int a,b; printf(max=%d,max(a,b);int a=13,b=-8;运行结果:运行结果:max=13extern int a,b;int max() int z; z=ab?a:b; return(z);main() printf(max=%d,max();int a=13,b=

64、-8;/*ch8_17.c*/int a=3,b=5;max(int a, int b) int c; c=ab?a:b; return(c);main() int a=8; printf(max=%d,max(a,b);例例 外部变量与局部变量外部变量与局部变量运行结果:运行结果:max=8int i;main() void prt(); for(i=0;i5;i+) prt();void prt() for(i=0;i5;i+) printf(“%c”,*); printf(“n”);例例 外部变量副作用外部变量副作用运行结果:运行结果:*例例 auto 变量的作用域变量的作用域main(

65、) 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=1x=1作用域作用域x=1作用域作用域x=3作用域作用域x=5作用域作用域main() void increment(void); increment(); increment(); increment();void increment(void) int x=0; x+

66、; printf(“%dn”,x);例例 局部静态变量值具有可继承性局部静态变量值具有可继承性运行结果:运行结果:1 1 1main() void increment(void); increment(); increment(); increment();void increment(void) static int x=0; x+; printf(“%dn”,x);运行结果:运行结果:1 2 3例例 变量的寿命与可见性变量的寿命与可见性int i=1;main() static int a; register int b=-10; int c=0; printf(-MAIN-n); pri

67、ntf(i:%d a:%db:%d c:%dn,i,a,b,c); c=c+8; other(); printf(-MAIN-n); printf(i:%d a:%db:%d c:%dn,i,a,b,c); i=i+10; other();other() static int a=2; static int b; int c=10; a=a+2; i=i+32; c=c+5; printf(-OTHER-n); printf(i:%d a:%db:%d c:%dn,i,a,b,c); b=a;-Main-i:1 a:0 b:-10 c:0 -Other-i:33 a:4 b:0 c:15 -M

68、ain-i:33 a:0 b:-10 c:8-Other-i:75 a:6 b:4 c:15全局i1main: a0b:-10registermain:c0静态存储区动态存储区other: a2other: b0other: c10843315443other: c10675156main() void gx(),gy(); extern int x,y; printf(“1: x=%dty=%dn”,x,y); y=246; gx(); gy();void gx() extern int x,y; x=135; printf(“2: x=%dty=%dn”,x,y);int x,y;void

69、 gy() printf(“3: x=%dty=%dn”,x,y);例例 用用extern扩展外部变量作用域扩展外部变量作用域运行结果:运行结果:1: x=0 y=02: x=135 y=2463: x=135 y=246例例 引用其它文件中的外部变量引用其它文件中的外部变量int global;extern float x;main() int local;.extern int global;static int number;func2().float x;static int number;func3() extern int global;.file1.cfile2.cfile3.c

70、例例 引用其它文件中的变量,输出引用其它文件中的变量,输出a b和和a的的m次方次方int a; /* ch7-21.c */main() int power(int n); int b=3,c,d,m; printf(Enter the number a and its power:n); scanf(%d,%d,&a,&m); c=a*b; printf(%d*%d=%dn,a,b,c); d=power(m); printf(%d*%d=%d,a,m,d);/* ch7-22.c*/extern int a;int power(int n) int i,y=1; for(i=1;i=n;

71、i+)y*=a; return(y); int i=1; main()/* lec9-7 */ int i,j; i=reset(); for(j=1;j=3;j+) printf(i=%d,j=%dn,i,j); printf(next(i)=%dn,next(i); printf(last(i)=%dn,last(i); printf(new(i+j)=%dn,new(i+j); int reset() return(i); int next(int j) j=i+; return(j); int last(int j) static int i=10; j=i-; return(j);

72、int new(int i) int j=10; return(i=j+=i); 例例:求下列程序运行结果求下列程序运行结果i=1,j=1new(i)=1last(i)=10new(i+j)=12i=1,j=2next(i)=9new(i+j)=13i=1,j=3next(i)=3last(i)=8new(i+j)=14l 8.10 内部函数与外部函数内部函数与外部函数u 8.10.1 内部函数内部函数 函数首部:函数首部:static 返回值类型返回值类型 函数名(形参表)函数名(形参表) 作用域:只可被作用域:只可被本文件本文件中的函数调用。其它文件中中的函数调用。其它文件中可以有与其可以

73、有与其同名同名的函数,但的函数,但互不干扰互不干扰。 u 8.10.2 外部函数外部函数 函数首部:函数首部:extern 返回值类型返回值类型 函数名(形参表)函数名(形参表) 作用域:可被作用域:可被其它文件其它文件中的函数调用。中的函数调用。 注注:一般一般extern可省,但在调用它的可省,但在调用它的其它文件其它文件中要用中要用extern进行声明。进行声明。作业8.98.108.118.15例例:一个程序由一个程序由5个文件组成个文件组成如何编译,连接和运行这如何编译,连接和运行这个程序?个程序?/ * f1.c */extern add(int,int);extern sub(i

74、nt,int);extern mult(int,int); extern float divs(int,int);int x,y; void main() scanf(%d,%d,&x,&y); printf(tadd=%dn,add(x,y); printf(tsub=%dn,sub(x,y); printf(tmult=%dn, mult(x,y); printf(tdivs=%fn,divs(x,y); / * f2.c */extern int x,y;add(int x, int y) return x+y; / * f3.c */extern int x,y;sub(int x,

75、int y) return x-y; / * f4.c */extern int x,y;mult(int x, int y) return x*y; / * f5.c */extern int x,y;float divs(int x, int y) if (y=0) return 0; else return (float)x/y; 用用#include命令把其他文件命令把其他文件包含进来。包含进来。(相当于相当于复复制制到其中而到其中而形成一个文件形成一个文件)二、文件包含方法二、文件包含方法/ * f1.c */extern add(int,int);extern sub(int,in

76、t);extern mult(int,int); extern float divs(int,int);int x,y;void main() scanf(%d,%d,&x,&y); printf(tadd=%dn,add(x,y); printf(tsub=%dn,sub(x,y); printf(tmult=%dn, mult(x,y); printf(tdivs=%fn,divs(x,y); / * f11.c */#include “f2.c”#include “f3.c”#include “f4.c”#include “f5.c”int x,y;void main() scanf(%d,%d,&x,&y); printf(tadd=%dn,add(x,y); printf(tsub=%dn,sub(x,y); printf(tmult=%dn, mult(x,y); printf(tdivs=%fn,divs(x,y);

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号