《C++程序设计》(第2版)-第5章-函数课件_第1页
《C++程序设计》(第2版)-第5章-函数课件_第2页
《C++程序设计》(第2版)-第5章-函数课件_第3页
《C++程序设计》(第2版)-第5章-函数课件_第4页
《C++程序设计》(第2版)-第5章-函数课件_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

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

文档简介

第五章函数——结构化程序设计基础第五章函数——结构化程序设计基础15.1概述

结构化程序设计的一个重要思想就是程序设计要模块化:将一个软件系统自顶向下分解成若干个简单的、独立的、功能单一的子系统。每个子系统称为一个模块,在C语言中表现为函数。即C的全部工作均由各种不同功能的函数完成。

复杂问题优点:功能单一完整,可以独立设计,单独调试。易于维护,通用性强。5.1.1函数概念b函数a函数C函数d函数e函数main()主函数f函数必须的,起点库函数各函数之间的关系称之为接口(参数,返回值),函数-函数通过接口通讯,交换数据。5.1概述结构化程序设计的一个重要思想就是程序设计2函数特点:

一段相对独立的程序,但不能独立运行。

建立函数称为“函数的定义”,使用函数称为“函数的调用”;调用其他函数的函数称为“主调函数”,被调用的函数称为“被调函数”。除主函数外,其他函数都不能独立运行。库函数与自定义函数被调用的函数可以是系统提供的库函数(TurboC提供300多个库函数),也可以是用户根据需要自己编写设计的函数(本章内容)。main函数(主函数)是每个程序执行的起始点

main(系统定义)函数可以调用其他任何函数,但不能被其他任何函数所调用。一个C程序总是从main函数开始执行(不论main函数在程序中的位置),在main函数中结束。函数特点:一段相对独立的程序,但不能独立运行。3函数分类(从不同角度):①定义:

库函数:C系统提供,不需定义和说明,在程序前加文件包含可直接调用。如:printf(“%d”,a)、sqrt(10.5)

用户定义函数:按需要编写的函数(本章讲述)。②功能:

有返回值函数:向主调函数返回一个执行结果。

无返回值函数:完成特定的任务,不返回执行结果(void)。③数据传送:

有参函数:定义时带有参数(形参),调用时必须给出参数(实参)。在主调函数与被调函数之间进行数据传递。

无参函数:定义时不带参数,与主调函数之间没有数据传递。④函数使用:

内部函数:只能在本编译文件中调用的函数(static)。

外部函数(默认):允许其它编译文件中调用的函数(extern)。函数分类(从不同角度):①定义:②功能:③数据传送:④45.1.2函数的定义(先定义,后使用)1.定义格式:

type

函数名(形参表)

{

说明语句; 功能语句;

}有返回值函数,应含有return语句。int

max(intx,inty){

intz;

z=x>=y?x:y;

return(z);}2.说明:

①一个函数(定义)由函数头(说明函数类型、函数名称及参数)和函数体(由{}括起来的声明部分、执行部分)两部分组成.③参数表说明参数的类型和名称,用“,”分隔。无参函数没有参数,但“()”号不能省略,也可以定义为“void”。voidBell(void){printf(“\007”);}函数体②函数类型就是返回值的类型(基本类型、构造类型)。默认为int,如果无返回值,应定义为void类型。注意:函数可以被主函数或其它函数调用,也可以调用其它函数,但不能调用主函数,不能单独运行。5.1.2函数的定义(先定义,后使用)1.定义格式:有55.1.3函数的调用1、调用格式:

函数名(实参表)

一般函数调用方式有三种:语句形式:max(a,b);表达式形式:c=max(a,b)*2+3;函数参数:printf(“%d”,max(b,d));例:inta=3,b=4;max(a,b);用逗号分隔的常量、变量、表达式、函数等,在函数调用时,必须有确定值。无参函数不能省略()。5.1.3函数的调用1、调用格式:一般函数调用方式有三种62、调用过程:(当主调函数执行到函数调用语句时)voidmain(void){inta,b,c;scanf(“%d,%d”,&a,&b);

c=max(a,b);printf(“%5d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}(1)计算实参的值,给形参分配内存,从右到左向函数传值,赋值给形参。23abXy23(2)程序转移到函数中运行,执行到一个return语句,由函数名把值带回到主调函数,程序返回到主调函数的调用处继续执行。z3c3(3)如果没有return语句,由最后一个}返回一个不确定的值!注意:函数的形参和实参是函数间传递数据的通道,故二者在个数、类型和顺序上要一一对应。2、调用过程:(当主调函数执行到函数调用语句时)void7注意:函数调用只能把实参的值传递给形参,而不能把形参的值反向传递给实参。#include<>voids(intn){

n=n+100;printf("Sub:n=%d\n",n);}voidmain(void){intn;scanf("n=%d",&n);s(n);printf("\nMain:n=%d\n",n);

}运行结果:n=15Sub:n=115Main:n=15可见:在函数调用过程中,形参的值发生改变时,对实参的值并不产生影响。例:注意:函数调用只能把实参的值传递给形参,而不能把形参的值反向83、函数的返回值格式1:return(表达式);或:

return表达式;格式2:return;

(应在定义函数时用void说明类型。)

函数中可以出现多个return语句,遇到一个return语句,则返回值,且返回调用函数,继续执行。intmax(intx,inty){if(x>=y)

returnx;

returny;}

⑵返回值的类型应与函数的类型一致,如不一致,以函数类型为准,先转换为函数类型后,再返回。int

max(void){floatz;…

returnz;/*z先转化为整型*/}

⑶为了确保参数和返回值类型正确,一般须在函数调用前对其类型和参数的类型加以说明,称之为原型声明。intimax(int,int)

;voidmain(void){intx,y,z;…z=imax(x,y);

…}

原型声明语句,加“;”3、函数的返回值格式1:return(表达式);或:ret94、函数的声明(1)被调函数为系统函数在程序清单的开头处写上由该函数的头文件组成的包含命令(scanf()和printf()可例外)。如:#include<>

#include<math.h>(2)被调函数为用户函数需在主调函数体内(仅能被主调函数调用)或体外(可被其后的任何函数调用)进行函数声明。声明格式:

type

函数名

(形参表);有一种情况可不需对主调函数说明,而直接使用。☆被调函数定义在主调函数之前。voidmain(){longfa(int);/*函数的原型声明*/longsum;sum=1+fa(2)+fa(3)+fa(4)+fa(5)+fa(6);printf(sum=%ld\n”,sum);}longfa(intn)/*函数的定义*/{inti;longy=1;for(i=1;i<=n;i++)y=y*i;returny;}4、函数的声明(1)被调函数为系统函数(2)被调函数为用10举例:通过函数求

xn

。#include<stdio.h>doublepow(float,int);voidmain(void){inti;for(i=1;i<=9;i++)printf(“%d,%f\n”,i,

pow(2.5,i)

);}doublepow(floatx,intn){inti;doublep=1;for(i=1;i<=n;i++)p=p*x;return(p);}原型声明。被调函数调用函数。定义函数。主调函数举例:通过函数求xn。#include<stdio.115.2函数间的数据传递

函数相对独立,但不孤立,它们通过调用时的①参数传递②函数的返回值③全局变量(后面介绍)来相互联系。在调用过程中,主调函数和被调函数存在数据的相互传递。传递包括两方面:⑴主调函数将值传递给被调函数;⑵被调函数将结果返回给主调函数。主调函数被调函数向被调函数传递值将结果返回给主调函数数据的传递方式:值传递和地址传递实参形参5.2函数间的数据传递函数相对独立,但不孤立,它们125.2.1值传递方式

通过实参与形参的结合,将数据值传递给形参,形参和实参各自占用不同的存储单元,形参的改变不影响实参(单向传递)。#include<stdio.h>voidchange(int,int);voidmain(void){inta,b;scanf(“%d,%d”,&a,&b);change(a,b);

printf(“%d%d\n”,a,b);}voidchange(inta,intb){intc;c=a;a=b;b=c;}主调函数被调函数a、b形参a、b实参传递实参233返回(值不定)abbac2232建立形参a、b=??5.2.1值传递方式通过实参与形参的结合,将数据135.2.2地址传递方式形参实参均为地址(数组名、指针),数据在主调函数和被调函数中占据相同的存储单元,形参的改变将影响到实参。#include<stdio.h>voidmain(){voidfun(intb[]);inta[10],i;for(i=0;i<10;i++)scanf(“%d”,&a[i]);

fun(a);

for(i=0;i<10;i++)printf(“%d”,a[i]);}

voidfun(intb[]){intmax,k,i;max=b[0];k=0;for(i=1;i<10;i++)if(max<b[i]){max=b[i];k=i;}max=b[0];b[0]=b[k];b[k]=max;return;}ab2000H2012Hab2000H2002H2┇482000H例:将数组中的最大值与第一个数交换┇5.2.2地址传递方式形参实参均为地址(数组名、145.2.3标准库函数

C语言很多功能都由标准库函数(系统函数)完成。它将一些常用功能模块编写成函数,分门别类地放在函数库中供用户使用。如I/O、常用数学函数等,用户可随时从库中调用。不同的C编译系统,库函数数量不等,但常用函数则大同小异。1.库函数的调用在程序开始处用#include将该类函数的头文件包含进来。文件包含的作用相当于函数的原型声明。2.库函数的分类标准C的库函数有300多种,给用户提供了良好的接口,为方便记忆查找(常用库函数要记住

),对函数进行了分类。①数学函数:#include<math.h>

②输入输出函数:#include<>③字符串处理函数:#include<string.h>④其他函数:#include<>

例题见p122~1255.2.3标准库函数C语言很多功能都由标准库函155.3数组与函数数组作为函数参数有两种方式:⒈数据元素作为函数参数;⒉数据名作为函数参数5.3数组与函数数组作为函数参数有两种方式:⒈数据元素作161.数组元素作函数实参(同普通变量)#include<>

voidtest(intx)/*定义一个无返回值函数,其形参为整型*/{printf(“%d”,(x>0)?x:0);}void

main(void){inta[5],i;printf(“input5number\n”);for(i=0;i<5;i++)

{

scanf(“%d”,&a[i]);test(a[i]);

}

/*每输入一个值,调用一次test,实参为该数组元素*/}1.数组元素作函数实参(同普通变量)#include<>17举例:通过函数求数组元素的平均值。#include<stdio.h>floatmean(intdata[],int);voidmain(void){intarray[10]={1,2,3,4,5,6,7,8,9,10};floatav;av=mean(array,10);printf(“av=%f\n%d”,av,array[0]);}floatmean(intdata[],intnum){inti;floatavg=0;for(i=0;i<num;i++)avg+=data[i];avg/=num;return(avg);}1.形参为无下标数组;无下标数组。data[0]=-1;intdata[10]形参为有下标数组。2.形参为有下标数组。说明:

⑴二种方法的实质都是传递地址,可以混用。⑵形参的任何改变都影响实参。⑶函数中对数组的操作,下标不要超过数组的下标范围。2.数组名作为函数参数举例:通过函数求数组元素的平均值。#include<std185.4函数的嵌套调用和递归调用5.4.1函数的嵌套调用C语言不允许嵌套定义。但允许函数嵌套调用,即被调函数中又调用其它函数。

mian函数①调用a函数结束a函数调用b函数b函数②③④⑤⑥⑦⑧⑨两层嵌套的执行过程5.4函数的嵌套调用和递归调用5.4.1函数的嵌套调用19例:求三个数中最大数和最小数的差值。#include<>intdif(intx,inty,intz);intmax(intx,inty,intz);intmin(intx,inty,intz);voidmain(){inta,b,c,d;scanf("%d%d%d",&a,&b,&c);d=dif(a,b,c);printf("Max-Min=%d\n",d);}intdif(intx,inty,intz){returnmax(x,y,z)-min(x,y,z);}intmax(intx,inty,intz){intr;r=x>y?x:y;return(r>z?r:z);}intmin(intx,inty,intz){intr;r=x<y?x:y;return(r<z?r:z);}main()调用函数dif输出结束dif函数max函数调用函数max调用函数minmin函数例:求三个数中最大数和最小数的差值。#include<>i205.4.2函数递归调用概念:函数直接或间接地自我调用称为函数递归调用。intfun1(intx){…z=fun1(y);…}intfun1(intx)intfun2(intt){{……z=fun2(y);c=fun1(a);……}}直接引用自身。间接引用自身。递归在没有控制条件的情况下是无穷的递归。voidmain(void){printf(“*****\n”);

main();}只有通过控制条件,使递归调用终止,才具有应用价值。voidmain(void){printf(“*****\n”);ch=getchar();

if(ch!=‘9’)main();}5.4.2函数递归调用概念:函数直接或间接地21递归举例:求n!。n!=1

n=0或n=1n(n-1)!

n>1f(n)=1

n=0或n=1nf(n-1)

n>1#include<stdio.h>longlfac(long);voidmain(void){longi,x;scanf(“%ld”,&i);x=lfac(i);printf(“\n%ld”,x);}longlfac(longn){if(n==0||n==1)return1;

elsereturn(n*lfac(n-1));}lfac(4)4*lfac(3)3*lfac(2)2*flac(1)2*13*2*14*3*2*1递推回归递归举例:求n!。n!=1n=0或n=225.5变量的存储类型及作用域

变量是内存数据的抽象,即将内存地址、数据表示抽象成一个符号。此外,变量还有存储类型,存储类型确定了变量在时间上的生存期和空间上的作用域。变量的说明格式:存储类型

类型变量名表;确定变量在内存中的表示方法。确定变量的生存期和作用域。该项省略表示auto存储类型。变量的存储类型有以下四种:⑴自动类型auto⑵寄存器类型register⑶静态类型static⑷外部类型extern5.5变量的存储类型及作用域变量是内存数据的23⒈auto存储类型定义在复合语句的开始处。块内生存块内有效。#include<stdio.h>voidmain(void){

autointa,b;scanf(“%d,%d”,&a,&b);if(b>a){

intiTemp;iTemp=a;a=b;b=iTemp;}printf(“Max=%d”,a);}ab的作用域iTemp的作用域。生存期:执行到复合语句建立内存变量。执行出复合语句变量消亡。iTemp⒉register存储类型作用域和生存期和auto相同,差别在于,如果CPU内部的寄存器空闲,则使用寄存器作为变量的存储单元,以提高速度。主要用于循环变量,且应该是整形和字符型。⒈auto存储类型定义在复合语句的开始处。块内生存块内有效。24⒊static(静态)存储类型作用域:在定义的复合语句内引用,出了复合语句不可见。生存期:从定义直到程序结束,执行出{}时,原值并不消失,只是不能引用。voidrow(void);voidmain(void){intb;for(b=1;b<=9;b++)row();}voidrow(void){

inta=1;

intb;for(b=1;b<=9;b++)printf(“%5d”,a*b);printf(“\n”);a++;}CHAP6EX6staticCHAP6EX5说明静态变量。a的作用域生存期从编译开始到程序结束。⒊static(静态)存储类型作用域:在定义的25⒋外部变量(extern存储类型)外部变量是定义在任何模块之外的变量。也称为全局变量。作用域:从定义直到文件结束。生存期:在程序的整个执行过程中。任何函数对外部变量的修改都会影响其他函数对外部变量引用时的值。#include<stdio.h>voidadd(void);inta,b,c;voidmain(void){scanf(“%d,%d”,&a,&b);add();printf(“%d”,c);}voidadd(void){c=a+b;}外部变量。作用域⒋外部变量(extern存储类型)外部变量是定义在任何模块之26关于外部变量的几点说明:⑴外部变量可以通过说明改变其作用域。voidmain(){…}inti;/*i为外部变量*/voidmax(inta,intb){…}作用域externi;新的作用域⑵外部变量可以被不同的文件共享。

inta;

externinta;文件1定义的外部变量。文件2通过说明使用文件1的外部变量。如果只希望在本文件中使用,可以加static说明。static关于外部变量的几点说明:⑴外部变量可以通过说明改变其作用域。27关于外部变量的几点说明:⑶模块设计的原则:内聚性强,耦合性弱。外部变量的使用占用内存资源且增加模块的耦合性,因此,应尽量不使用外部变量。⑷当模块中出现和全局变量同名的局部变量时,局部变量在模块中优先。inta;voidmain(void){a=5;…}voidfun(…){

inta;

a=5;}关于外部变量的几点说明:⑶模块设计的原则:内聚28外部变量应用举例:用外部变量交换两个变量的值。#include<stdio.h>inta,b;voidmain(void){scanf(“%d,%d”,&a,&b);fun();printf(“a=%d,b=%d\n”,a,b);}voidfun(void){intc;c=a;a=b;b=c;}a、b外部变量。ab外部变量应用举例:用外部变量交换两个变量的值。#includ29外部变量的副作用#include<stdio.h>inti;voidprt(void);voidmain(void){for(i=0;i<5;i++)prt();}voidprt(void){for(i=0;i<5;i++)printf(“%c”,’*’);printf(“\n”);}函数的作用:打印五个*,再回车。几次调用函数?i==0i==0i==0i==0i==0i==1i==2i==3i==4i==5i==5i==5i==5i==5外部变量的副作用#include<stdio.h>函数的作305.6编译预处理C语言除了说明语句、执行语句及控制语句外,还有一类编译预处理语句。该类语句的作用是在编译时对程序作一定的处理,满足特定的处理要求。编译预处理是C语言的重要特征。编译预处理语句的语法形式:#关键词参数表编译预处理语句不用;作为结束标志!⒈宏定义预处理⑴不带参数的宏定义作用:定义常量名,提高程序的可读性,便于修改。格式:

#define宏名字符串#definePI

voidmain(void){floatr;scanf(“%f”,&r)

printf(“%f\n”,PI*r*r);}编译时用字符串替代宏名。5.6编译预处理C语言除了说明语句、执行31说明:⑴宏名一般用大写;⑵编译时用字符串无条件替代宏名;;…PI*r*r;*r*r⑶宏名的有效范围,从定义到程序尾。也可以通过#undef修改定义范围。voidmain(void){…}#undefGG的范围⑷可以在宏定义的字符串中使用已定义的宏名。⑸””字符串中的宏名不替换。#define

R

#define

PI

#defineSPI*R*Rprintf(“S=%f”,S);不替换。说明:⑴宏名一般用大写;;;*r*r⑶宏名的有32⑵带参数的宏定义格式:

#define宏名(参数表)含参数的字符串#defineS(a,b)a*b…area=S(4,3);替换过程:①将实际参数替换宏定义的参数。②替换字符串中的参数。③替换整个宏。4*3带参的宏与函数的区别:带参宏不分配内存单元,不返回值,只是在编译时按规则替换。关于带参宏的说明:①要严格按格式书写,否则会造成错误。#defineS(a,b)a*bS(3,4)被替换成:(a,b)a*b(3,4)②参数有可能用到表达式时,参数字符要加()。#defineS(r)PI*r*rS(a+b)替换为:PI*a+b*a+b#defineS(r)PI*(r)*(r)S(a+b)替换为:PI*(a+b)*(a+b)⑵带参数的宏定义格式:#define宏名(参数表)33⒉文件包含格式:

#include<被包含的文件名>

#include”被包含的文件名”<>表示编译系统定义路径;“”表示用户指明路径。作用:将指定的文件的内容和当前文件一起编译。说明:⑴一个#include只能包含一个文件。⑵被包含文件可以嵌套包含文件。⑶一般将宏定义及函数的原型声明放在包含文件中。⑷被包含的文件一般扩展名为.h,称为头文件。⒉文件包含格式:<>表示编译系统定义路径;作用:将指定的34文件包含举例:求半径为r的园面积、园周长。#include

“my.h”voidmain(void){floatr,fArea,fLen;scanf(“%f”,&r);

fArea=S(r);

fLen=L(r);

printf(“Area=%f,Len=%f”,fArea,fLen);}floatS(floatr){returnPI*r*r;}floatL(floatr){return2*PI*r;}#include<stdio.h>floatS(float);floatL(float);文件包含举例:求半径为r的园面积、园周长。#include35⒊条件编译C语言可以通过条件控制,让编译系统编译不同的程序段,从而提高程序的移植性并方便调试。条件编译有三种形式:#ifdef标识符programseg1#elseprogramseg2#endif#ifndef标识符programseg1#elseprogramseg2#endif123#if表达式programseg1#elseprogramseg2#endif条件?满足编译程序段1不满足编译程序段2⒊条件编译C语言可以通过条件控制,让编译系统36举例:通过条件编译选择求最大值或最小值#include<stdio.h>

voidmain(void){inta,b;scanf(“%d,%d”,&a,&b);#ifdefMAX

printf(“%d”,a>=b?a:b);#else

printf(“%d”,a<=b?a:b);#endif}#defineMAX#include<stdio.h>

voidmain(void){inta,b;scanf(“%d,%d”,&a,&b);printf(“%d”,a>=b?a:b);}举例:通过条件编译选择求最大值或最小值#include<37第五章函数——结构化程序设计基础第五章函数——结构化程序设计基础385.1概述

结构化程序设计的一个重要思想就是程序设计要模块化:将一个软件系统自顶向下分解成若干个简单的、独立的、功能单一的子系统。每个子系统称为一个模块,在C语言中表现为函数。即C的全部工作均由各种不同功能的函数完成。

复杂问题优点:功能单一完整,可以独立设计,单独调试。易于维护,通用性强。5.1.1函数概念b函数a函数C函数d函数e函数main()主函数f函数必须的,起点库函数各函数之间的关系称之为接口(参数,返回值),函数-函数通过接口通讯,交换数据。5.1概述结构化程序设计的一个重要思想就是程序设计39函数特点:

一段相对独立的程序,但不能独立运行。

建立函数称为“函数的定义”,使用函数称为“函数的调用”;调用其他函数的函数称为“主调函数”,被调用的函数称为“被调函数”。除主函数外,其他函数都不能独立运行。库函数与自定义函数被调用的函数可以是系统提供的库函数(TurboC提供300多个库函数),也可以是用户根据需要自己编写设计的函数(本章内容)。main函数(主函数)是每个程序执行的起始点

main(系统定义)函数可以调用其他任何函数,但不能被其他任何函数所调用。一个C程序总是从main函数开始执行(不论main函数在程序中的位置),在main函数中结束。函数特点:一段相对独立的程序,但不能独立运行。40函数分类(从不同角度):①定义:

库函数:C系统提供,不需定义和说明,在程序前加文件包含可直接调用。如:printf(“%d”,a)、sqrt(10.5)

用户定义函数:按需要编写的函数(本章讲述)。②功能:

有返回值函数:向主调函数返回一个执行结果。

无返回值函数:完成特定的任务,不返回执行结果(void)。③数据传送:

有参函数:定义时带有参数(形参),调用时必须给出参数(实参)。在主调函数与被调函数之间进行数据传递。

无参函数:定义时不带参数,与主调函数之间没有数据传递。④函数使用:

内部函数:只能在本编译文件中调用的函数(static)。

外部函数(默认):允许其它编译文件中调用的函数(extern)。函数分类(从不同角度):①定义:②功能:③数据传送:④415.1.2函数的定义(先定义,后使用)1.定义格式:

type

函数名(形参表)

{

说明语句; 功能语句;

}有返回值函数,应含有return语句。int

max(intx,inty){

intz;

z=x>=y?x:y;

return(z);}2.说明:

①一个函数(定义)由函数头(说明函数类型、函数名称及参数)和函数体(由{}括起来的声明部分、执行部分)两部分组成.③参数表说明参数的类型和名称,用“,”分隔。无参函数没有参数,但“()”号不能省略,也可以定义为“void”。voidBell(void){printf(“\007”);}函数体②函数类型就是返回值的类型(基本类型、构造类型)。默认为int,如果无返回值,应定义为void类型。注意:函数可以被主函数或其它函数调用,也可以调用其它函数,但不能调用主函数,不能单独运行。5.1.2函数的定义(先定义,后使用)1.定义格式:有425.1.3函数的调用1、调用格式:

函数名(实参表)

一般函数调用方式有三种:语句形式:max(a,b);表达式形式:c=max(a,b)*2+3;函数参数:printf(“%d”,max(b,d));例:inta=3,b=4;max(a,b);用逗号分隔的常量、变量、表达式、函数等,在函数调用时,必须有确定值。无参函数不能省略()。5.1.3函数的调用1、调用格式:一般函数调用方式有三种432、调用过程:(当主调函数执行到函数调用语句时)voidmain(void){inta,b,c;scanf(“%d,%d”,&a,&b);

c=max(a,b);printf(“%5d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}(1)计算实参的值,给形参分配内存,从右到左向函数传值,赋值给形参。23abXy23(2)程序转移到函数中运行,执行到一个return语句,由函数名把值带回到主调函数,程序返回到主调函数的调用处继续执行。z3c3(3)如果没有return语句,由最后一个}返回一个不确定的值!注意:函数的形参和实参是函数间传递数据的通道,故二者在个数、类型和顺序上要一一对应。2、调用过程:(当主调函数执行到函数调用语句时)void44注意:函数调用只能把实参的值传递给形参,而不能把形参的值反向传递给实参。#include<>voids(intn){

n=n+100;printf("Sub:n=%d\n",n);}voidmain(void){intn;scanf("n=%d",&n);s(n);printf("\nMain:n=%d\n",n);

}运行结果:n=15Sub:n=115Main:n=15可见:在函数调用过程中,形参的值发生改变时,对实参的值并不产生影响。例:注意:函数调用只能把实参的值传递给形参,而不能把形参的值反向453、函数的返回值格式1:return(表达式);或:

return表达式;格式2:return;

(应在定义函数时用void说明类型。)

函数中可以出现多个return语句,遇到一个return语句,则返回值,且返回调用函数,继续执行。intmax(intx,inty){if(x>=y)

returnx;

returny;}

⑵返回值的类型应与函数的类型一致,如不一致,以函数类型为准,先转换为函数类型后,再返回。int

max(void){floatz;…

returnz;/*z先转化为整型*/}

⑶为了确保参数和返回值类型正确,一般须在函数调用前对其类型和参数的类型加以说明,称之为原型声明。intimax(int,int)

;voidmain(void){intx,y,z;…z=imax(x,y);

…}

原型声明语句,加“;”3、函数的返回值格式1:return(表达式);或:ret464、函数的声明(1)被调函数为系统函数在程序清单的开头处写上由该函数的头文件组成的包含命令(scanf()和printf()可例外)。如:#include<>

#include<math.h>(2)被调函数为用户函数需在主调函数体内(仅能被主调函数调用)或体外(可被其后的任何函数调用)进行函数声明。声明格式:

type

函数名

(形参表);有一种情况可不需对主调函数说明,而直接使用。☆被调函数定义在主调函数之前。voidmain(){longfa(int);/*函数的原型声明*/longsum;sum=1+fa(2)+fa(3)+fa(4)+fa(5)+fa(6);printf(sum=%ld\n”,sum);}longfa(intn)/*函数的定义*/{inti;longy=1;for(i=1;i<=n;i++)y=y*i;returny;}4、函数的声明(1)被调函数为系统函数(2)被调函数为用47举例:通过函数求

xn

。#include<stdio.h>doublepow(float,int);voidmain(void){inti;for(i=1;i<=9;i++)printf(“%d,%f\n”,i,

pow(2.5,i)

);}doublepow(floatx,intn){inti;doublep=1;for(i=1;i<=n;i++)p=p*x;return(p);}原型声明。被调函数调用函数。定义函数。主调函数举例:通过函数求xn。#include<stdio.485.2函数间的数据传递

函数相对独立,但不孤立,它们通过调用时的①参数传递②函数的返回值③全局变量(后面介绍)来相互联系。在调用过程中,主调函数和被调函数存在数据的相互传递。传递包括两方面:⑴主调函数将值传递给被调函数;⑵被调函数将结果返回给主调函数。主调函数被调函数向被调函数传递值将结果返回给主调函数数据的传递方式:值传递和地址传递实参形参5.2函数间的数据传递函数相对独立,但不孤立,它们495.2.1值传递方式

通过实参与形参的结合,将数据值传递给形参,形参和实参各自占用不同的存储单元,形参的改变不影响实参(单向传递)。#include<stdio.h>voidchange(int,int);voidmain(void){inta,b;scanf(“%d,%d”,&a,&b);change(a,b);

printf(“%d%d\n”,a,b);}voidchange(inta,intb){intc;c=a;a=b;b=c;}主调函数被调函数a、b形参a、b实参传递实参233返回(值不定)abbac2232建立形参a、b=??5.2.1值传递方式通过实参与形参的结合,将数据505.2.2地址传递方式形参实参均为地址(数组名、指针),数据在主调函数和被调函数中占据相同的存储单元,形参的改变将影响到实参。#include<stdio.h>voidmain(){voidfun(intb[]);inta[10],i;for(i=0;i<10;i++)scanf(“%d”,&a[i]);

fun(a);

for(i=0;i<10;i++)printf(“%d”,a[i]);}

voidfun(intb[]){intmax,k,i;max=b[0];k=0;for(i=1;i<10;i++)if(max<b[i]){max=b[i];k=i;}max=b[0];b[0]=b[k];b[k]=max;return;}ab2000H2012Hab2000H2002H2┇482000H例:将数组中的最大值与第一个数交换┇5.2.2地址传递方式形参实参均为地址(数组名、515.2.3标准库函数

C语言很多功能都由标准库函数(系统函数)完成。它将一些常用功能模块编写成函数,分门别类地放在函数库中供用户使用。如I/O、常用数学函数等,用户可随时从库中调用。不同的C编译系统,库函数数量不等,但常用函数则大同小异。1.库函数的调用在程序开始处用#include将该类函数的头文件包含进来。文件包含的作用相当于函数的原型声明。2.库函数的分类标准C的库函数有300多种,给用户提供了良好的接口,为方便记忆查找(常用库函数要记住

),对函数进行了分类。①数学函数:#include<math.h>

②输入输出函数:#include<>③字符串处理函数:#include<string.h>④其他函数:#include<>

例题见p122~1255.2.3标准库函数C语言很多功能都由标准库函525.3数组与函数数组作为函数参数有两种方式:⒈数据元素作为函数参数;⒉数据名作为函数参数5.3数组与函数数组作为函数参数有两种方式:⒈数据元素作531.数组元素作函数实参(同普通变量)#include<>

voidtest(intx)/*定义一个无返回值函数,其形参为整型*/{printf(“%d”,(x>0)?x:0);}void

main(void){inta[5],i;printf(“input5number\n”);for(i=0;i<5;i++)

{

scanf(“%d”,&a[i]);test(a[i]);

}

/*每输入一个值,调用一次test,实参为该数组元素*/}1.数组元素作函数实参(同普通变量)#include<>54举例:通过函数求数组元素的平均值。#include<stdio.h>floatmean(intdata[],int);voidmain(void){intarray[10]={1,2,3,4,5,6,7,8,9,10};floatav;av=mean(array,10);printf(“av=%f\n%d”,av,array[0]);}floatmean(intdata[],intnum){inti;floatavg=0;for(i=0;i<num;i++)avg+=data[i];avg/=num;return(avg);}1.形参为无下标数组;无下标数组。data[0]=-1;intdata[10]形参为有下标数组。2.形参为有下标数组。说明:

⑴二种方法的实质都是传递地址,可以混用。⑵形参的任何改变都影响实参。⑶函数中对数组的操作,下标不要超过数组的下标范围。2.数组名作为函数参数举例:通过函数求数组元素的平均值。#include<std555.4函数的嵌套调用和递归调用5.4.1函数的嵌套调用C语言不允许嵌套定义。但允许函数嵌套调用,即被调函数中又调用其它函数。

mian函数①调用a函数结束a函数调用b函数b函数②③④⑤⑥⑦⑧⑨两层嵌套的执行过程5.4函数的嵌套调用和递归调用5.4.1函数的嵌套调用56例:求三个数中最大数和最小数的差值。#include<>intdif(intx,inty,intz);intmax(intx,inty,intz);intmin(intx,inty,intz);voidmain(){inta,b,c,d;scanf("%d%d%d",&a,&b,&c);d=dif(a,b,c);printf("Max-Min=%d\n",d);}intdif(intx,inty,intz){returnmax(x,y,z)-min(x,y,z);}intmax(intx,inty,intz){intr;r=x>y?x:y;return(r>z?r:z);}intmin(intx,inty,intz){intr;r=x<y?x:y;return(r<z?r:z);}main()调用函数dif输出结束dif函数max函数调用函数max调用函数minmin函数例:求三个数中最大数和最小数的差值。#include<>i575.4.2函数递归调用概念:函数直接或间接地自我调用称为函数递归调用。intfun1(intx){…z=fun1(y);…}intfun1(intx)intfun2(intt){{……z=fun2(y);c=fun1(a);……}}直接引用自身。间接引用自身。递归在没有控制条件的情况下是无穷的递归。voidmain(void){printf(“*****\n”);

main();}只有通过控制条件,使递归调用终止,才具有应用价值。voidmain(void){printf(“*****\n”);ch=getchar();

if(ch!=‘9’)main();}5.4.2函数递归调用概念:函数直接或间接地58递归举例:求n!。n!=1

n=0或n=1n(n-1)!

n>1f(n)=1

n=0或n=1nf(n-1)

n>1#include<stdio.h>longlfac(long);voidmain(void){longi,x;scanf(“%ld”,&i);x=lfac(i);printf(“\n%ld”,x);}longlfac(longn){if(n==0||n==1)return1;

elsereturn(n*lfac(n-1));}lfac(4)4*lfac(3)3*lfac(2)2*flac(1)2*13*2*14*3*2*1递推回归递归举例:求n!。n!=1n=0或n=595.5变量的存储类型及作用域

变量是内存数据的抽象,即将内存地址、数据表示抽象成一个符号。此外,变量还有存储类型,存储类型确定了变量在时间上的生存期和空间上的作用域。变量的说明格式:存储类型

类型变量名表;确定变量在内存中的表示方法。确定变量的生存期和作用域。该项省略表示auto存储类型。变量的存储类型有以下四种:⑴自动类型auto⑵寄存器类型register⑶静态类型static⑷外部类型extern5.5变量的存储类型及作用域变量是内存数据的60⒈auto存储类型定义在复合语句的开始处。块内生存块内有效。#include<stdio.h>voidmain(void){

autointa,b;scanf(“%d,%d”,&a,&b);if(b>a){

intiTemp;iTemp=a;a=b;b=iTemp;}printf(“Max=%d”,a);}ab的作用域iTemp的作用域。生存期:执行到复合语句建立内存变量。执行出复合语句变量消亡。iTemp⒉register存储类型作用域和生存期和auto相同,差别在于,如果CPU内部的寄存器空闲,则使用寄存器作为变量的存储单元,以提高速度。主要用于循环变量,且应该是整形和字符型。⒈auto存储类型定义在复合语句的开始处。块内生存块内有效。61⒊static(静态)存储类型作用域:在定义的复合语句内引用,出了复合语句不可见。生存期:从定义直到程序结束,执行出{}时,原值并不消失,只是不能引用。voidrow(void);voidmain(void){intb;for(b=1;b<=9;b++)row();}voidrow(void){

inta=1;

intb;for(b=1;b<=9;b++)printf(“%5d”,a*b);printf(“\n”);a++;}CHAP6EX6staticCHAP6EX5说明静态变量。a的作用域生存期从编译开始到程序结束。⒊static(静态)存储类型作用域:在定义的62⒋外部变量(extern存储类型)外部变量是定义在任何模块之外的变量。也称为全局变量。作用域:从定义直到文件结束。生存期:在程序的整个执行过程中。任何函数对外部变量的修改都会影响其他函数对外部变量引用时的值。#include<stdio.h>voidadd(void);inta,b,c;voidmain(void){scanf(“%d,%d”,&a,&b);add();printf(“%d”,c);}voidadd(void){c=a+b;}外部变量。作用域⒋外部变量(extern存储类型)外部变量是定义在任何模块之63关于外部变量的几点说明:⑴外部变量可以通过说明改变其作用域。voidmain(){…}inti;/*i为外部变量*/voidmax(inta,intb){…}作用域externi;新的作用域⑵外部变量可以被不同的文件共享。

inta;

externinta;文件1定义的外部变量。文件2通过说明使用文件1的外部变量。如果只希望在本文件中使用,可以加static说明。static关于外部变量的几点说明:⑴外部变量可以通过说明改变其作用域。64关于外部变量的几点说明:⑶模块设计的原则:内聚性强,耦合性弱。外部变量的使用占用内存资源且增加模块的耦合性,因此,应尽量不使用外部变量。⑷当模块中出现和全局变量同名的局部变量时,局部变量在模块中优先。inta;voidmain(void){a=5;…}voidfun(…){

inta;

a=5;}关于外部变量的几点说明:⑶模块设计的原则:内聚65外部变量应用举例:用外部变量交换两个变量的值。#include<stdio.h>inta,b;voidmain(void){scanf(“%d,%d”,&a,&b);fun();printf(“a=%d,b=%d\n”,a,b);}voidfun(void){in

温馨提示

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

评论

0/150

提交评论