C语言程序设计 函数.ppt_第1页
C语言程序设计 函数.ppt_第2页
C语言程序设计 函数.ppt_第3页
C语言程序设计 函数.ppt_第4页
C语言程序设计 函数.ppt_第5页
已阅读5页,还剩44页未读, 继续免费阅读

下载本文档

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

文档简介

1、第六章 函数,第六章 函数教学要求 一、学习要求 1.掌握函数的定义与调用 2.掌握函数间参数的传递方法 二、学习重点 1.函数的返回值 2.函数实参与形参的关系 3.函数间参数的传递,6.1 函数概述,一、c语言函数与模块化程序设计方法,程序员在设计一个复杂的应用程序时,往往把整个程序划分为若干功能较为单一的程序模块,然后分别予以实现,最后再把所有的程序模块像搭积木一样装配起来,这种策略被称为模块化程序设计方法。,在c语言中,函数是程序的基本组成单位,因此可以利用函数作为程序模块来实现c语言程序。,需要定义成函数的程序段所具备的条件(供参考):,1、程序中可能有重复出现的相同或相似的计算片度

2、。可以考虑从中抽取共同的东西,定义为函数。,2、程序中具有逻辑独立性的片段。即使这种片段 只出现一次,也可以考虑把它定义成独立的函数。这种做法的主要作用是分解程序复杂性,使之更容易理解和把握。,二、函数的分类,从定义角度分为库函数和自定义函数。,从兼有其他语句功能角度分为有返回值函数和无返回值函数。,从函数间数据传送角度分为无参函数和有参函数。,三、主函数,C语言中所有的函数定义都是平行的。即不允许在一个函数体内定义另一个函数。但是函数之间允许相互调用。,C程序里总有一个叫main的函数,称为主函数。C程序的执行总是从main函数开始,完成对其它函数的调用后再返回到main函数,最后由main

3、函数结束整个程序。注意:任何其它函数都不可以调用主函数。,6.2函数的定义和调用,一、函数的定义,1、无参函数的一般形式,类型说明符 函数名( ) 类型说明 语句 ,说明:(1)类型说明符指明了函数返回值的类型。函数名是由用户定义的标识符,函数名后的括号不可缺少。,函数头,函数体,(2)在函数体中也有类型说明,这是对函数体内部所用到的变量的类型说明。,(3)定义函数时应写返回值类型,如果无参函数没有返回值,函数类型可以用关键字void。,例1:定义一个无参函数。,void hello( ) printf(“Hello, how do you do?n”); ,这里,hello是一个无参函数的函

4、数名,当被其它函数调用时,输出“Hello, how do you do?“字符串。,2、有参函数的一般形式,类型说明符 函数名(形式参数表 ) 类型说明 语句 ,说明:(1)行参表中给出的参数称为形式参数(简称行参),它们可以是各种类型的变量,各参数之间用逗号隔开。在进行函数调用时,主调函数将赋予这些形式参数实际的值(简称实参)。,(2)形式参数既然是变量,当然必须有类型说明。,例2:定义一个函数,求两个数中较小的数。,int min (int a, int b) if (ab) return b; else return a; ,程序分析:,(1)min函数是一个整型函数,其返回值是一个整

5、数。行参为整型变量a,b。a,b的具体值是有主调函数在调用时传送过来的。,(2)在中的函数体内,除行参外没有使用别的变量,因此只有语句没有变量类型说明。,(3)函数体中的return语句是把a(或b)的值作为函数的值返回给主调函数。在有返回值的函数中至少应该有一个return语句。,注意:函数可以放在程序的任何位置,既可以放在main之前, 也可以放在main之后。,例3 :求两个数中较小的数,#include int min (int a, int b) if (ab) return b; else return a; void main() int x,y,z; printf(“pleas

6、e input 2 number:n”); scanf(“%d %d”, ,3、函数原型说明,在主调函数调用某函数之前应对被调函数进行原型说明。在主调函数中对被调用作说明的目的是使编译程序知道被调函数返回值类型,以便在主调函数中按此种类型对返回值作相应的处理。,对被调函数的原型说明,其一般格式为:,类型说明符 被调函数名(类型 行参1,类型 行参2);,或者为,类型说明符 被调函数名(类型 ,类型 );,在c语言中,下面几种情况可以不用对被调函数作原型说明。,(1)被调函数出现在主调函数之前;,(2)在定义所有函数之前,在函数外预先说明了各个函数的类型;,(3)对库函数的调用。,建议在任何情况

7、下都写函数原型的编程风格。,二、函数的调用,1、函数调用的形式,在c语言中, 函数调用的一般形式为:,函数名(实际参数表);,对无参函数调用时没有实际参数表。实际参数表中的参数可以是常数、变量和表达试,各实参之间用逗号隔开。,在c语言中, 可以用以下几种方式调用函数:,(1)函数表达式。函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。,例:z=min(x, y);,(2)函数语句。在函数的末尾加上一个分号构成 函数语句。,例:hello(); printf (“ %d ”, a);,(3)函数作为另一个函数的实参。,例:z=min (a, min (b, c); print

8、f (“%d” ,min (x, y);,2、函数的返回值,函数被调用以后,将执行函数体的程序段,取得并返回给主调函数一个值,称为函数的返回值。,(1)函数的返回值只能通过return语句返回给主调函数。其一般格式为:,return 表达式;,或者为:,return (表达式);,(2)函数的返回值类型和函数定义中函数的类型应保持一致;,(3)无返回值的函数, 可以定义为空类型,类型说明符为void。,例4:编写一个函数power(a,n),用来计算a的n次方,并在主函数调用该函数计算3的7次方。,#include void main() int power(int a,int n); int

9、 x,y,s; scanf(%d %d, ,int power(int a,int n) int i,s1=1; for (i=1;i=n;i+) s1=s1*a; return s1; ,本节习题:,1、写一个函数void kitty(int k),当主程序调用kitty(k)时,屏幕上会出现k行”hello,kitty“。,2、写一个函数 long int fact(int n)用来计算n的阶乘,并在主程序中调用并计算 s=1!+2!+10!。,6.3 函数参数传递,一、传值调用,传值调用就是在函数调用时,把实参的值复制到函数的行参中。,行参和实参的功能是实现数据传送。发生函数调用时,主调

10、函数把实参的值复制一份传送给被调函数的行参,从而实现主调函数向被调函数传送数据。,函数的行参和实参具有以下特点:,1、行参变量只有在被调用时才分配内存单元。调用结束时,立刻释放内存单元,因此,行参只在函数内部有效。,2、实参可以是常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们必须有确定的值,以便把这些值传送给行参。,3、实参和行参在数量、类型、顺序上应严格一致,否则会发生“类型不匹配”的错误。,4、函数调用中发生的数据传送是单向的,即只能把实参的值传送给行参,而不能把行参的值反向传送给实参。因此,在函数调用中,行参的值发生改变,却不会影响实参的值发生变化。,例1:分

11、析下面的程序,#include void main() int sqr (int x); int t=10; printf(“%d的平方是:%d”,t,sqr(t); ,int sqr(int x) x=x*x; return x; ,切记:传给函数的只是参数的复制品,函数内部的所有变化都不会引起主调函数中变量发生改变。,二、传址调用,所谓地址调用就是在函数调用时,将实参数据的存储地址作为参数传递给行参。,传址调用的特点是:,行参和实参占用同样的内存单元,函数中对行参值的改变也会改变实参的值。因此,可实现主调函数与被调函数之间数据的双向传递。,注意:由于行参和实参都必须是地址,通常将行参定义为

12、指针变量,当把变量的地址作为实参传递给行参指针时,指针指向的变量就是实参变量,从而实现数据的双向传递。,例2: 分析下面的程序:,#include void main() void swap (int x, int y); int a=10,b=20; printf(“%d,%dn”,a,b); swap(a,b); printf(“%d,%dn”,a,b); ,void swap(int x,int y) int t; t=x; x=y; y=t; ,两条printf语句输出的结果都是10,20。,例3: 利用函数调用交换两个整型变量的值:,#include void main() void

13、 swap (int *x, int *y); int a=10,b=20; printf(“%d,%dn”,a,b); swap( ,void swap(int *x,int *y) int t; t=*x; *x=*y; *y=t; ,第一条printf语句输出10,20; 第二条printf语句输出20,10。,例4: 分析下面的程序:,#include void main() void swap (int *x, int *y); int a=10,b=20; printf(“%d,%dn”,a,b); swap( ,void swap(int *x,int *y) int *t; t

14、=x; x=y; y=t; ,两条printf语句输出的结果都是10,20。,6.4 函数与数组,数组可以作为函数的参数使用,进行数据传送。数组用作函数参数有两种形式:一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的行参和实参使用。,一、数组元素作函数实参,数组的每一个元素与普通变量并无区别。因此,它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传递给行参,实现单向的值传递。,例1:判别一个整数数组中各元素的值,若大于等于0则输出该值;若小于0则输出相反值。,#include void main() int jdz(int x); int

15、 a5; int i; for (i=0;i5;i+) scanf(“%d”, ,int jdz( int x) if (x=0) return x; else return x; ,二、数组名作为函数参数,用数组名作函数参数的特点:,1、用数组名作函数参数时,要求行参和相对应的实参都必须是相同类型的数组,必须有明确的数组类型说明,当两者类型不一致时,会发生错误。,2、用数组名作函数参数时,不是发生值传递,即不是把实参数组中的每一个元素对应地传递给行参数组中的每一个元素。,数组名是数组的首地址,因此,用数组名作为函数参数时实际上是进行的地址传递,即把实参数组的首地址赋予行参数组名。行参数组在得

16、到该地址以后,两个数组名同时指向同一段内存单元,即为同一数组。此时,对行参数组的操作就是对实参数组的操作。,例2:数组中存放了一个学生5门课程的成绩,求平均成绩。,#include void main() float aver (float a5); float score5,av; int i; printf(input 5 scores:n); for (i=0;i5;i+) scanf(%f, ,float aver(float a5) int i; float p,s=0; for (i=0;i5;i+) s=s+ai; p=s/5; return p; ,例3:用数组名作函数参数修改

17、例1。,#include void main() void jdz(int a5) ; int b5; int i; for (i=0;i5;i+) scanf(%d, ,void jdz(int a5) int i; for (i=0;i5;i+) if (ai0)ai=-ai; ,用数组名作函数参数,要注意以下几点:,1、行参数组和实参数组的类型必须一致;,2、行参可以定义为指向数组类型的指针,当实参数组名传递给行参指针后,指针指向实参数组。,3、行参数组和实参数组的长度可以不相同,因为在调用时,只传送首地址而不传送数组长度。但是,当形参数组长度和实参数组长度不一致时,有时可能会产生程序结

18、果的错误。,4、在函数行参表中, 允许不给出数组的长度。,例4:修改例2,并分析结果,#include void main() float aver (float a5); float score5,av; int i; printf(input 5 scores:n); for (i=0;i5;i+) scanf(%f, ,float aver(float a8) int i; float p,s=0; for (i=0;i8;i+) s=s+ai; p=s/8; return p; ,5、多维数组也可以作为函数参数。在函数定义时对行参数组可以指定每一维的长度,也可以省去第一维的长度。因此,

19、以下写法都是合法的:,int fun(int a34); int fun(int a4);,本节作业: 1、用函数实现将一个整型数组中的元素用冒泡法从小到大排序,并在主函数中调用该函数。 2、用函数实现两个数的交换,并在主函数中进行调用(要求:函数体中不采用中间变量)。,6.5函数与指针,数组名是数组的首地址,而指针变量的值也是地址,因此,函数的行参也可以用指针变量来表示.在参数传递的过程中,作为行参的指针变量和作为实参的数组名指向相同的内存单元。,例1:数组a中存放了一个学生5门课程的成绩,求平均成绩,用指针变量实现。,#include void main() float aver (flo

20、at a5); float score5,av; int i; printf(input 5 scores:n); for (i=0;i5;i+) scanf(%f, ,float aver(float *p) int i; float ave,s=0; for (i=0;i5;i+) s=s+*(p+i); ave=s/5; return ave; ,利用指针解决问题的方案包括三方面:,1、被调函数定义时用指针参数;,2、被调函数里通过指针参数间接访问被指针指向的变量;,3、函数调用时把地址传给被调函数。,一、返回指针的函数,在C语言里,允许一个函数的返回值是一个指针(即地址),这种返回指针

21、值的函数称为指针型函数。定义指针型函数的一般形式为:,类型说明符 *函数名(行参表) 函数体语句; ,其中:函数名前加了一个*号,表明这是一个指针型函数,即返回值是一个指针。类型说明符表示该指针指向的数据类型。,例1:通过指针函数,输入一个17之间的整数,输出对应的星期名。,#include void main() char *dayname(int n); int i; printf(please input a number:n); scanf(%d, ,char *dayname(int n) char *week=error,monday,tuesday,wednesday,thurs

22、day,friday,saturday,sunday; if (n=1) ,二、指向函数的指针,C语言规定, 一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。可以给函数的这个首地址赋予一个指针变量,使该指针指向该函数。然后通过指针变量调用该函数。把这种指向函数的指针变量称为“函数指针变量”。,函数指针变量定义的一般形式为:,类型说明符 (*指针变量名)(参数表);,其中,类型说明符表示被指向函数的返回值类型,后面的参数表对应于被指向函数的行参。,例如:int (*pf)(int x);,这里定义了一个指向函数的指针变量pf,被指向函数的返回值是整型,并且被指向函数有一个整型行参。,例2:用函数指针变量形式调用函数求最大值、最小值。,#include int min( int x,int y) if (xy) return y; else return x; ,int max( int x,int y) if (xy) return x; else retu

温馨提示

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

评论

0/150

提交评论