一个较大的程序一般要划分成多个程序模块_第1页
一个较大的程序一般要划分成多个程序模块_第2页
一个较大的程序一般要划分成多个程序模块_第3页
一个较大的程序一般要划分成多个程序模块_第4页
一个较大的程序一般要划分成多个程序模块_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 第8章 函 数8.1 概述 一个较大的程序一般要划分成多个程序模块,或把多次重复执行的一段程序独立编写一个模块,这些模块称为函数,一个C程序就是由一个主函数和若干函数构成的。 main()abcdehgfij主函数函数1函数2函数21 第8章 函 数例 8.1 main() printstar(); print_message(); printstar(); printstar() printf(* * * * * * * * * * * * * * * * * * * * * * * * * * n); print_message() printf(* How do you do ! *n

2、); 主函数调用打印星号函数调用打印信息函数再调用打印星号函数打印星号函数打印信息函数2关于函数说明:一个源程序由若干函数组成,源文件为编译单位, 即一次全部编译完。2.一个C程序可由一个或若干个源文件组成,可 别编辑、编译。经连接生成可执行文件。3.一个C 程序从main函数开始,在main函数中结束。main() ;。4.所有函数都是平行的,即相互独立,互不从属。5.从用户角度,函数分为:(1)标准函数(如:数学计算, 字符处理)(2)用户定义的函数:解决专门问题。36、从函数形式上,分为: (1)有参函数:主调用函数和被调函数之间 有参数传递。 主调用函数(实参) 被调函数(形参) (2

3、)无参函数:主调函数和被调函数之间无 参数传递,一般被调函数也 不带回返回值。传送4 8.2 函数定义的一般形式1、无参函数的定义形式: 类型标识符 函数名( ) 说明部分 语句 无参函数无返回值,可省略类型标识符符。如:printstar() printf(“* * * * * * * * * * n”); 52、有参函数定义的一般形式: 类型标识符 函数名(形式参数列表) 声明部分 语句 例: int max(x,y) int x,y; int z; z=xy?x:y; return(z); 声明部分声明部分定义整型函数max()函数max的返回值63、允许有空函数的存在,形式为: 类型表

4、示符 函数名( ) 如: int max(a,b) int a,b; int max() 函数max的返回值一般是待编函数7 8.3 函数参数和函数的值8.3.1 形式参数和实际参数形式参数:在定义函数时函数名后面括号中的 变量名称形式参数,简称形参。实际参数:在调用函数时函数名后面括弧中的 表达式称实际参数,简称实参。举例说明: main()主函数调用前面定义的max函数:8main ()int a, b,c;scanf(%d,%d,&a, &b);c=max(a,b);printf(Max is %d,c);max(int x, int y)int z;z=xy?x:y;return (z

5、);实参形参形参声明给返回参数赋值返回max的值9关于形参和实参的说明:1、形参在函数没被调用时,不分配内存单元; 只有被调用时才分配,调用结束后释放。2、实参可以是常量、变量或表达式,但要有确 定值。形参如果是数组名,则将数组的首地 址传递给对应的形参。3、在被定义的函数中,必须指定形参类型。 如:max (int x, int y);4、形参与实参对应的类型和个数必须一致。 如: max(a,b) max (int x, int y);10关于形参和实参的说明:5、实参对形参变量的数据传递是“值传递”, 形参值的改变并不会改变主调函数实参值。6、ANSIC允许在列出形参列表时同时定义类型。

6、 int max(int x, int y) 等价于: int max( x, y) int x, int y 11 8.3.2 函数的返回值 主函数调用函数得到返回值。对返回值说明:1、函数返回值通过 return语句获得: 一个函数中可以包含多个return 语句,但只 能有一个起作用。以下retutrn形式都可以: return z;或return(z);或return(xy?x:y);2、定义函数类型必须与返回值类型一致。int max(float x,float y)int z;return zchar letter(char c1,char c2)char creturn cdou

7、ble min(int x,int y)double z;return z12 8.3.2 函数的返回值 主函数调用函数得到返回值。对返回值说明:3、函数返回值类型不同于函数类型时,自动转 换为函数类型。 max (float x,float y); float z;return (z)4、如果函数中不使用return语句,函数将带回 一不确定的值。5、为了明确表示“不带回值”可用void定义函数 为无类型(空类型)。因max是整型所以z 转换为整型13main ( )float a, b;int c;scanf(%f,%f,&a,&b);c=max(a,b);printf(Max is %d

8、,c);max(x,y)float x,y;float z;z=xy?x:y;return (z);定义为实型默认为整型输出整型数14 main ( )float a, b;int c;scanf(%f,%f,&a,&b);c=max(a,b);printf(Max is %d,c);max(x,y)float x,y;xy?x:y;无返回语句值不定15void printstar()printf(* * * * * * * * * * * * * * * * * * * * * * * * * * n);void print_message()printf(* How do you do !

9、 *n);main()printstar();print_message();printstar(); 定义空类型函数定义空类型函数调用函数语句不变16 8.4 函数的调用8.4.1 函数调用的一般形式: 函数名(实参列表);Turbo C传递实参自右向左。8.4.2 函数调用的方式: 按函数出现的位置分三种调用方式:1、函数语句: 把函数作为一个语句。 printstar();2、函数表达式:把函数作为一个表达式 c=a+max(a,b);3、函数参数:函数调用作为另一个函数的实参。 d=max(c,max(a,b);17main()int i=2,p;p=f(i,+i);printf(%d

10、,p);int f(int a,int b)int c;if(ab)c=1;else if(a=b)c=0;else c=-1;return(c);先计算+i结果?修改为后计算+i18 8.4.3 对被调函数的说明 一个函数调用另一个函数须具备条件:1、被调用函数必须存在。2、如果被调函数是库函数,则需在文件开头用 #inlcude形式包含所在库文件。 比如用到:sqrt 则需包含 math.h strcpy() 则需包含 string.h getchar() 则需包含 stdio.h3、调用自定义的函数,一般应在主调函数内对 调用函数的返回值类型作说明。 一般形式: 类型说明符 被调用函数的

11、函数名( )19main()float a, b, c;float add();scanf(%f,%f,&a,&b);c=add(a,b);printf(sum is %f,c);float add(x,y)float x,y;float z;z=x+y;return (z);对被调用的函数进行说明否则出错 被调用的函数20 C规定,以下情况调用函数前不用说明:1、函数返回整型或字符型。2、被调函数在主调函数之前定义(举上例)。3、在函数开头或函数外部已说明了函数类型。如: float add(); main() . folat add(float x,float y) 再函数外部说明21 8

12、.5 函数的嵌套调用 C规定: 函数不能嵌套定义,但能嵌套调用。 嵌套调用的示意: main 函数 a 函数 b 函数 调用a函数 调用b函数 结束调用返回22main()int n;scanf(%d,&n);printf(%d,sum(n);sum(int m)int i,s;s=0;for(i=1;i1)递归结束递归调用调用递归函数age(5)=age(4)+2age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+227 递归函数调用执行过程mainage(5)=18age(4)=16age(3)=14age(2)=12age(1)=10age(3)+

13、2age(2)+2age(1)+2age(4)+210输出age(5)age(5)age函数n=5n=4n=3n=2n=1288.8 用递归方法求 n! 一般方法:main()int i, sum=1, n;scanf(%d,&n);for(i=1;i1main()int n;scanf(%d,&n);printf(%d,fac(n);float fac(n)int c; if(n=1|n=0)c=1; else c=n*fac(n-1); return(c);递归结束递归调用31计算实型数(大数的阶乘),修改如下:main()int n;float fac();scanf(%d,&n);pr

14、intf(%f,fac(n);float fac(int n)float c; if(n=1|n=0)c=1; else c=n*fac(n-1); return(c);32Hanoi(汉诺)塔问题 相传古代印度“布拉玛庙”的僧侣们玩的一种游戏,游戏的装置是一块铜板上有三根针,最左针上由大到小串有64个金盘,游戏的规则是将64个金盘移到最右针上,每次移动一个金盘且始终保持小盘在大盘上面。 计算移动的次数: 264-1=18,446,744,073,709,511,615次 计算机计算每微秒移动1次需100万年 如果人每秒移动1次需5800亿年 33Hanoi(汉诺)塔问题这是一个只有用递归方法

15、才能解决的问题。 AC,AB,CB, AC,BA,BC,AC将 n-1个盘子从一根针上移到另一根针上将1个盘子从一根针上移到另一根针上ABC小中小大小中小(23 1=7次)34Hanoi(汉诺)塔问题 老和尚的做法:如果有一个和尚能将63个盘子从一个针移到另一个针就可以了, 老和尚只需做:(1)命令第2个和尚将63个盘子从A针移到B针; (2)自己最后的一个盘子从A针移到C针;(3)再命令第2个和尚将63个盘子从B针移到C针; 实际问题并没解决,第2个和尚又找第3个和尚 第1人 =第2人=第3人 =第64人 63个盘62个盘1个盘35问题分析归纳:将N个盘子从A针移到针可分为3步:(1)将A针

16、上n-1个盘子借助C针移到B针; (2) 把A针上剩下的一个盘子移到C针;(3)将B针上n-1个盘子借助A针移到C针; 第1步和第3步都是移动n-1盘子,只是针不同,归纳: “将one针上n-1个盘子移到two针借助three针”只是(1)和(3) one, two,three和A,B,C的对应关系不同第1步对应关系: one A, two -B, three C第3步对应关系: one B, two -C, three A可把上面3个步骤化成2步:1,移动n-1个盘子(小和尚任务层层下放,递归完成);2,由大和尚将一个盘子从一个针移到另一个针.36void move(char x,char

17、y)printf(%c-%cn,x,y);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 diskes:);scanf(%d,&m);printf(The step to moving %3d diskes:n,m);hanoi(m,A,B,C);从X移到Y从1针移到3针从1针移到

18、3针从1针借助3针移到2针从2针借助1针移到3针37 8.7 数组作为函数的参数1、数组元素作为函数的实参:例如:比较两个数的最大值max(x,y)return (xy?x:y);main( )int a2, max_num;scanf(%d,%d,&a0,&a1);max_num=max(a0,a1);printf(%dn,max_num);382、数组名作为函数的参数 即:实参和形参都使用数组名作为参数例8.11 有一个一维数组score, 存放10个学生成绩, 求平均成绩。float average(float array10)int i;float aver,sum=array0;fo

19、r(i=1;i5;i+)sum=sum+arrayi;aver=sum/5;return(aver);累加总分计算平均分回带结果累加单元赋初值39主函数:实现数据输入, 函数调用, 数据输出main()float score10,aver;int i;for(i=0;i5;i+)scanf(%f,&scorei);aver=average(score);printf(average score is %5.2f,aver);调用函数注意格式符40说明:1、应在主函数和被调函数之间分别定义数组;2、实参和形参类型应一致;3、形参数组大小可以不指定,可由另一参数传递。 float averge(a

20、rray,n) float array ; int n; . 4、数组名作为函数参数,实现“地址传递” 传递地址值。(实参,形参共用同一地址)修改上例查看结果(内存单元)41例8.13用将数组中10个数由小到大排序。 “冒泡法”:是一边比较一边交换。 “选择法”:是比较一轮交换一次。 数据排序前 1与a0交换 3与a1交换 4与a2交换 6与a3交换选择法: a0 a1 a2 a3 a4 3 6 1 9 4 1 6 3 9 4 1 3 6 9 4 1 3 4 9 6 1 3 4 6 9 42void sort(int a,int n) 选择法排序int i,j,k,t;for(i=0;in;i

21、+) k=i; for(j=i+1;jn;j+) if(ajak)k=j; t=ak;ak=ai;ai=t;main()int b10,i;for(i=0;i10;i+) scanf(%d,&bi);sort(b,10);for(i=0;i10;i+) printf(%6d,bi); 记住小数的下标每轮第一个数的下标将小数交换到前面43 8.8 局部变量和全局变量8.8.1 局部变量在函数内定义的变量,只在本函数内有效,称为局部变量。例如:add(int a,int b)a=a+b;return(a);main()int a,b; a=10;b=20; printf(add=%d,add(a,

22、b); printf(main=%d,a); a,b局部于add函数a,b局部于main函数 结果? 加c后结果?main()int a,b,c=0; a=10;b=20; int c; c=a+b; printf(c=%d,c); printf(add=%d,add(a,b); printf(main=%d,%d,a,c);getch();44局部变量说明:1、主函数内定义的变量,也只在本函数内有效。2、不同函数可以使用相同名字的变量,但表示 不同的变量。3、形参也是局部变量。4、复合语句定义的变量,只在该语句中有效。 main() int a,b; : int c; c=a+b; : :

23、a,b,c的有效范围a,b的有效范围458.8.2 全局变量在函数外定义的变量,为外部变量(全局变量)。int p=1,q=5; (外部变量)float f1(a)int a;int b,c;:char c1,c2; (外部变量)char f2(int x,int y)int i,j;:main()int m,n:c1c2的作用范围pq的作用范围46float max,min;float fun(float a,int n)int i;float av,sum=a0;max=min=a0;for(i=1;imax)max=ai; if(aimin)min=ai; sum=sum+ai; av=

24、sum/10; return(av);main()float s10; int i; for(i=0;i10;i+) scanf(%f,&si); printf(%f,%f,%f,max,min,fun(s,10);输入10个学生成绩到数组打印最高,最低和平均分定义全局变量回带3个值47关于全局变量说明:1、增加函数间数据联系的渠道,返回多个值。2、建议少使用全局变量,因降低通用性。3、如果外部变量和局部变量重名,则在局部变量的范围内,外部变量被“屏蔽”。int a,b;add(a)a=a+a;b=2*a;return(a);main()int a;a=10;printf(add=%d,add

25、(a);printf(main=%d,%d,a,b);a被屏蔽 结果?48 8.9 变量的存储类别 全局变量 局部变量 静态存储变量 动态存储变量静态存储方式:在程序运行期间分配固定存储空间动态存储方式:在程序运行期间根据需要动态分配 存储空间 从变量的作用域区分从变量值存在时间区分49 内存中供用户使用的空间在C语言中一个变量和函数有两个属性, 即: 数据类型: int , float, char 等 自动的(auto) 静态的(static) 寄存器的(register) 外部的(extern)存放全局变量存放局部变量, 形参, 保留地址程 序 区静态存储区动态存储区用户区 存储类别: 下

26、面分别介绍508.9.2 用auto声明局部自动变量前面函数中的局部变量都属于自动变量,自动变量说明可以省略。 int f(inta) auto int b,c=3; auto int b,c=3; int b,c=3;定义b,c为自动变量两个语句等价518.9.3 用static声明局部静态变量 如果在调用函数时,希望上次调用时的数据 不消失,可定义为局部静态变量,如: f(int a) auto b=0; static 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);定义c

27、为静态变量 结果?528.9.3 用static声明局部静态变量例8.18 打印1到5的阶乘。int fac(int n)static int p=1;p=p*n;return(p);main()int i;for(i=1;iy?x:y; return(z);main()extern A,B;printf(%d,max(A,B);int A=13,B=-8;2,再声明A, B为全局变量3,所以此处可用1,因为在函数后声明558.9.5 用extern声明全局变量2、如果在一个文件中引用另外一个文件中定义的全局变量, 则用extern 来进行说明:例8.21 给定b的值,输入a和m, 求ab和am的值。 文件:f1.c 文件:f2.cint A;main()int p(int); int b=3,c,d,m; scanf(%d,%d,&A,&m); c=A*b; printf(%d*%d=%dn,A,b,c); d=p(m); printf(%d*%d=%d,A,m,d);extern A;p(int n)int i,y=1;for(i=1;i=n;i+) y=y*A;return(y);声明A为全局变量568.11 如何运行一个多文件的程序一个源程序可以由多文件组成,运行一个多文件的程序的方法如下(如文件f1.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论