程序设计基础07函数的基本概念_第1页
程序设计基础07函数的基本概念_第2页
程序设计基础07函数的基本概念_第3页
程序设计基础07函数的基本概念_第4页
程序设计基础07函数的基本概念_第5页
免费预览已结束,剩余99页可下载查看

下载本文档

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

文档简介

程序设计基础(C语言)东北大学高级语言程序设计课程组课程网站:程序设计基础(C语言)函数的基本概念3模块化结构一个用C语言开发的软件由许多功能组成从组成上看,各个功能模块彼此有一定的联系,功能上各自独立,从开发过程上看,不同的模块可能由不同的程序员开发提出模块化设计怎样将不同的功能模块连接在一起,成为一个程序怎样保证不同的开发者的工作既不重复,又能彼此衔接支持这种设计方法的语言称为模块化程序设计语言4模块化结构C语言提供了模块化设计的功能模块化设计在程序设计中分而治之的策略将一个大的程序自上向下进行功能分解成若干个子模块模块对应了一个功能有自己的界面有相关的操作完成独立的功能各个模块可以分别由不同的人员编写和调试将不同的模块组装成一个完整的程序将所有的程序模块象积木一样装配起来5模块化结构C采用函数实现功能模块C语言中一个函数实现一个特定的功能一个C语言程序可以由一个主函数和若干个其它函数构成由主函数调用其它函数其它函数也可以相互调用同一个函数可以被一个函数或多个函数调用任意多次在设计时,往往将一些常用的功能模块编写成为函数,放在函数库中,供大家选用或多次调用,以减少重复性的编写程序

C程序的功能可以通过函数之间的调用实现方便的利用函数作为程序模块实现C语言程序设计的模块化6模块化结构C采用函数实现功能模块一个完整的C程序可以由多个源程序文件组成一个文件中可以包含多个函数C程序源程序文件1源程序文件i源程序文件n预编译命令函数1函数n函数体函数首部7模块化结构C采用函数的特点允许将一个程序写入不同的源文件每一个源文件可以独立编译一个源文件可以被不同的程序使用函数是最小的功能单位一个函数可以被不同的源文件的其他函数调用一个源文件由多个函数组成主函数可以放在任何一个源文件中一个C程序只有一个主函数main()不同源文件的组装可以通过工程文件实现8模块化结构C采用函数的优点程序设计变得简单和直观提高程序的易读性和可维护性C语言提供了丰富的库函数减少程序员的代码工作量允许用户根据需要定义函数提高了程序的开发速度和灵活性9什么是函数?什么是函数?函数是一段完成特定功能的程序可以用简单的方法为其提供必要的数据自动执行这段程序能保存执行后的结果将程序回到原处继续将程序中反复使用的程序定义为函数的形式10函数的种类用户使用的角度库函数在C语言的编译系统中,提供了很多若干已经编制好的函数,用户可以直接使用用户定义函数用户根据需求自己编写的一段程序,实现特定的功能函数的形式无参函数使用该函数时,不需提供数据,直接使用该程序段提供的功能,通常完成某一个处理任务有参函数使用该函数时,必须提供必要的数据,根据提供数据的不同,可能获得不同的结果11说明本例中共包含了两个函数主函数main()用户定义函数max()主函数可以定义在程序的任意位置函数的定义是平行的彼此相互独立不能嵌套定义在主函数中调用库函数调用用户函数例:求最大值函数#include<stdio.h>/*函数max()的原型说明*/intmax(intx,inty);

voidmain(){intn1,n2,n3,a;

scanf(“%d%d”,&n1,&n2,&n3);

a=max(n1,n2);

a=max(a,n3);

printf(“最大值是%d”,a);}/*函数max()的定义*/intmax(intx,inty){intz;

if(x>y)z=x;

elsez=y;

return(z);}函数举例程序设计基础(C语言)库函数13库函数C语言的库函数由编译系统提供的已设计好的函数,用户只需调用而无须实现C的库函数极大地方便了用户在编写C语言程序时,应当尽可能多地使用库函数提高程序的运行效率以及提高编程的质量函数库函数库是由系统建立的具有一定功能的函数的集合库中存放函数的名称和对应的目标代码,以及连接过程中所需的重定位信息用户也可以根据自己的需要建立自己的用户函数库14库函数库函数存放在函数库中的函数库函数具有明确的功能、入口调用参数和返回值头文件(又称包含文件)C语言库函数与用户程序之间进行信息通信时要使用的数据和变量在使用某一库函数时,使用#include对应该函数所在头文件提示不同版本的C语言具有不同的库函数用户使用时应查阅有关版本的C的库函数参考手册15库函数如何使用库函数?函数的功能及所能完成的操作参数的数目和顺序,以及每个参数的意义及类型返回值的意义及类型需要使用的包含文件要调用某个库函数,则需在程序的头部用包含命令(#include)将说明该函数原型的头文件包含进本程序中例如:include<math.h>16【例】库函数使用的例子#include<stdio.h>#include<stdlib.h>main(){inti,j,num;for(i=0;i<10;i++){num=rand()%10+1;for(j=0;j<num;j++)printf("*");printf("\n");}printf("\n");

}

本例是在屏幕上输出10行*,每一行*的个数是1~20之间的随机数,程序中用到了一个可以产生随机数的库函数——rand(),这个函数的调用格式为:

rand();调用结果返回一个随机数。库函数rand的原型说明在头文件stdlib.h中。库函数17随机函数的应用:

#include<stdlib.h>#include<stdio.h>#include<time.h>main(){inti;srand(time(NULL));

for(i=1;i<=20;i++){printf("%10d“,1+(rand()%10));

if(i%5==0)printf("\n");

}printf("\n");

}在随机函数时常见的错误是:使用srand()代替rand()函数产生随机数。库函数程序设计基础(C语言)函数定义19函数的定义概念就是为实现某一具体功能而编写的函数的程序块用户自定义函数程序员自行定义和设计的函数库函数一般只能提供一些低层服务的功能用户自定义的函数则能针对具体的应用实现一些特殊的功能20函数的定义函数定义的一般形式例

函数类型函数名(形参表说明)/*函数首部*/

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}intmax(intx,inty)

{intz;

if(x>y)z=x;

elsez=y;

return(z);

}21函数的定义函数定义的一般形式说明类型类型规定该函数返回值的类型函数返回值可以是除数组和函数外的任何合法的数据类型例:int、long、float、char、指针、结构体等系统默认的类型是整类型如果未指定类型,则返回值为整型可用void表示如果函数没有返回值

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}22函数的定义函数定义的一般形式说明函数名是用户自定义的标识符是C语言函数定义中唯一不可省略的部分需符合C语言命名规则的标识符用在程序中标识函数,并用该标识符调用函数一个好的函数名应该能够反映该函数的模块的功能函数名本身代表数值它代表了该函数的入口地址

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}23函数的定义函数定义的一般形式说明形参表(也称“形式参数”)形参表是用逗号分隔的一组变量说明作用是指出每一个形参的类型和形参的名称包括形参的类型和形参标识符当调用函数时,接受来自主调函数的数据,确定各参数的值形参表说明的两种表示形式:

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}intfunc(intx,inty)

{……}

intfunc(x,y)

intx,y;

{……}24函数的定义函数定义的一般形式说明函数体用{}括起来的部分是函数的主体函数体是一段体现函数功能的程序函数内部应有自己的说明语句和执行语句形式参数表中经过说明的变量可以在函数体内直接使用但函数内定义的变量不可以与形参同名提示函数体部分可以没有,空函数,但是每个函数体外面的一对{}不能省略任何情况下不允许一个函数内部定义另外一个函数(函数不能嵌套定义)

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}25函数的定义函数定义的一般形式说明函数返回值函数调用后函数体计算/执行的结果称为函数的返回值通过返回语句将计算结果带回主调函数函数返回值类型函数定义时的类型就是函数返回值的类型C语言要求函数定义的类型应当与返回语句中表达式的类型保持一致当两者不一致时,系统自动进行转换,将函数返回语句中表达式的类型转换为函数定义时的类型提示函数的类型决定着返回值的类型系统进行自动的转换会造成程序的不清晰、可读性差等

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}26函数的定义函数定义的一般形式说明函数返回值分析程序的运行结果

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}#include<stdio.h>

main()

{floata,b;

intc;

scanf("%f%f",&a,&b);

c=max(a,b);

printf("MAXis%d\n",c);

}

max(floatx,floaty)

{floatz;

z=x>y?x:y;

return(z);

}运行时,若从键盘输入:4.56.8结果为:627函数的定义函数定义的一般形式返回语句格式功能赋给当前被调函数一个值结束当前被调函数的执行,将表达式的值带回主调函数

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}return表达式;/*return(2*3)表示函数返回值为6

*/

return(表达式);/*return2*3表示函数返回值为6

*/

return;/*没有返回值*/28函数的定义函数定义的一般形式返回值语句提示函数的返回值只能有一个当函数中不需要指明返回值时可以写成:return;并不是函数执行后没有值只是没有被用户指定并由系统分配函数一个随机值函数中不需要指明返回值时可以不写返回语句此时,并不意味该函数不带回返回值,而是带回一个不确定的值,有可能给程序带来某种意外的影响

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}29函数的定义函数定义的一般形式返回值语句提示一个函数体内可以有多个返回语句,不论执行到哪一个,函数都结束,回到主调函数例如对带有返回值的函数,在调用时,可以将其作为同类型的一个变量一样使用例如

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}sign(intx)

{if(x>0)return(1);if(x==0)return(0);

if(x<0)renturn(-1);

}inta,b,c,max;

max=max(c,max(a,b));30函数的定义函数定义的一般形式返回值语句提示为了保证函数不返回任何值,C语言规定,可以定义无类型(void类型)函数,同时函数体可以省略使用return语句,如果使用也只能使用return;(不能带任何参数)

函数类型函数名(形参表说明)

{/*函数体*/

说明语句执行语句

[return;函数返回值]

}31函数的定义空类型说明没有返回值C语言规定,一个函数可以没有返回值,函数类型应明确定义为void(空)类型对于void(空)类型函数,系统保证不使函数带有任何值同时也禁止在调用函数中使用被调函数的值说明没有形参形参表明确地写明void,表示没有形式参数例如:voidmain(void)32函数的定义空类型格式说明void类型的函数不是调用函数之后不再返回,而是调用函数在返回时没有返回值void类型的函数与有返回值类型的函数在定义过程中没有区别,只是在调用时不同void类型的函数不能将函数调用放在表达式之中,只能在语句中单独调用void类型的函数一般用于完成一些规定的操作void函数名(形参表)

{……}33函数的定义空类型例题分析定义为“void”型的函数,在调用时不返回任何值,所以不能将其使用在赋值语句后表达式中在主调程序中引用了void函数。编系统在编译这个程序时,会提示错误信息:“notanallowedtypeinfunctionmain”例:voidprintchar(charc){

printf(“%c=%d”

,c,c);}main(){intk;

k=printchar(‘a’);

/*printchar没有返回值*/printf(“%d\n”,k);

}34问题1:voidfun1(a,b,c){printf(“%d%d%d”,a,b,c);}——??正确格式:voidfun1(inta,intb,intc)问题2:

floatfun2(floata,floatb){floata,b,c;

c=a+b;

return(c);}——??形参被重复定义问题3:已知函数abc的定义格式为:

voidabc()

{……}则函数定义中void的含义是____。A.执行函数abc后,函数没有返回值B.执行函数abc后,函数不再返回C.执行函数abc后,可以返回任何类型D.以上答案都是错误的函数的定义35【例】指出如下程序段中的错误。intfun(void){printf(“insidefun\n”);intfun1(void){printf(“insidefun1\n”);}}intsum(intx,inty){intresult;result=x+y;}(c)intsum(intx){if(x==0)return0;elsex+sum(x-1);}错误:函数fun1定义在函数fun的内部.改正:将函数fun1的定义移出函数fun之外.错误:函数应该返回一个整数值,但却没有返回值语句.改正:添加一个return语句.returnresult;或删除后returnx+y;错误:没有返回x+sum(x-1)的结果.改正:把else块中的语句改为:returnx+sum(x-1);函数的定义36函数的定义无参函数的定义例:编写一个函数,输出“cprogramming."。#include<stdio.h>

func2()

{printf(“&&&&&&&&&&&&&&&\n");

printf("cprogramming.\n");

printf(“&&&&&&&&&&&&&&&\n");

}

main()

{func2();

}37函数定义小结C语言的程序中函数很多,main是唯一不可缺少的函数是整个程序的主函数程序运行时,从主函数开始执行一个程序由多个函数组成时,主函数main与程序中其它函数的任意次序排列main作为最后一个函数放在文件结尾处,系统也总是要从main开始运行C语言的一个程序可以由多个文件组成每个文件可以单独编译将几个文件一起联接成一个可运行文件一个函数的定义不能跨越在两个文件中函数在一个文件中必须保持完整一个程序的多个函数定义中,不允许存在相同的函数名38函数定义小结C语言的函数可以分为两类带返回值的函数通过调用可以得到一个确定的值,该值就是所调用函数的返回值不带返回值函数不带返回值的函数通常只是一个“过程”只是用来完成某种操作主调函数并不需要它有任何的信息返回调用时可将其作为C的一个语句直接调用函数不能嵌套定义一个函数的定义不能从属与另外一个函数39无论有无形参,函数名后的()不能省略形式参数表中说明的形参,在函数体中不再需要说明可以同一般的变量完全一样直接使用函数体内部的变量说明与形参说明的含义不同前者说明函数体的一个局部变量,后者说明一个用于函数间传送数据的形式变量最好在形参列表中列出每个参数的类型即使参数是默认的int不应省略对每个形参的类型说明例如:floatmax(floatx,floaty)不能写成floatmax(foatx,y),此时y为系统缺省的int类型函数定义小结40应尽可能多的使用系统提供的库函数传递给函数的参数和函数定义中的相应的参数尽量不使用相同的名字选择有意义的参数名和函数名可以使程序具有良好的可读性可以避免过多地使用注释需要大量参数的函数可能包含较多的功能(任务)应该考虑将该函数分成完成单个任务的较小的函数函数原型、函数头部和函数调用应该具有一致的参数个数、参数类型、参数顺序和返回值类型函数定义小结41常见错误如果指定了非整型int类型的返回值类型,则省略函数定义中的返回值类型会导致语法错误忘记从应该返回一个值的函数返回该值会导致无法预料的错误ANSIC标准规定被省略的结果是不确定的、随机的从返回类型为void的函数返回一个值会导致语法错误定义函数时,在其参数列表的)后以“;”结束是一种语法错误形参的类型说明一定放在函数体{}内会导致语法错误在函数体内部对形式参数再次定义是一种语法错误函数定义小结程序设计基础(C语言)函数调用43函数调用定义一个函数调用另一个函数调用者称为主调函数被调用的函数称为被调函数主调函数使用被调函数的功能,称为对被调函数的调用函数调用的基本形式通过函数名函数的参数例:求最大值函数#include<stdio.h>intmax(intx,inty);

voidmain(){intn1,n2,a;

scanf(“%d%d”,&n1,&n2);

a=max(n1,n2);

printf(“最大值是%d”,a);}intmax(intx,inty){intz;

if(x>y)z=x;

elsez=y;

return(z);}44函数调用函数调用方式一般形式函数名(实参表)[;]说明函数名确定了被调函数的对象实参表函数调用时()内的变量名是执行被调函数时主调函数传递给形参的实际参数提示参数的类型、个数和次序应与函数要求的形式参数完全统一例:intfun3(){inti,j,k;

i=2;

j=i*i;

k=j*j;

printf(“%3d%3d%3d”

i,j,k);}

main()

{fun3();

}45函数调用函数调用方式按照函数在主调函数中的作用,函数的调用方式有以下三种形式函数语句函数表达式函数参数46函数调用函数调用方式函数语句作为C程序中的一条语句调用被调函数调用格式:

函数名(实参表);说明通常只完成一种操作,不带回返回值常用于调用一个可以忽略返回值或没有返回值的函数只要求函数完成一定的操作47函数调用函数调用方式函数表达式函数调用出现在一个表达式中,这个表达式称为函数表达式将函数的调用结果作运算符的运算分量格式

变量名=函数表达式;说明这种方式用于调用带有返回值的函数要求函数必须带回一个确定的值参与表达式的运算48函数调用函数调用方式函数参数函数调用作为另外一个函数的实际参数格式fun1(x,fun2);说明这种方式要求函数必须带回一个确定的值函数的参数也是表达式例m=max(max(a,b),c);或

printf(“%d”

,max(a,b));49函数声明o被调函数的声明一个函数要调用另外一个函数首先是被调用的函数必须存在其次还应在主调函数中对所有被调函数加以说明否则,在连接时会出现找不到所调用函数的错误信息函数的调用也应遵循“先定义后使用”的原则50函数声明被调函数的声明库函数的声明被调函数是C语言系统提供的标准库函数在源程序文件的开头处,使用#include命令,将存放所调用库函数的有关“头文件”包含到该程序文件中来#include命令的一般形式为

#include<math.h>#include”stdio.h”51函数声明被调函数的声明用户自定义函数的声明被调用函数为用户自己定义的函数一般情况下,应在主调用函数中对被调用函数(返回值)的类型进行说明形式说明为编译系统进行类型检查提供依据函数值是什么类型有多少个参数,每一个参数是什么类型的函数类型函数名(形参类型1形参名1,形参类型2形参名2…)52函数声明被调函数的声明用户自定义函数的声明提示:在下列情况下可以省略函数声明当函数的返回值为整型或字符型时如果在同一个文件中既定义函数,又调用该函数不论定义函数与调用函数在源程序中的位置关系如何,都可以省去函数说明此时系统对其自动按整型处理例:求两个非负数的最大公约数分析:采用“转辗相除”法若a>b,求a/b的余数r;若r=0,则b为最大公约数;若r!=0,则r->b,b->a,再一次进行a/b求余数r,r=0,b为最大公约数53源程序:

main(){inta,b,r;

scanf("%d%d",&a,&b);

r=gcd(a,b);

printf("gcd(a,b)is%d\n",r);

}

intgcd(x,y)intx,y;

{inta,b,t;

if(x<y){t=x;x=y;y=t;}a=x;b=y;

while(b!=0){t=a%b;a=b;b=t;}return(a);}声明的被调函数gcd(x,y)为int类型,所以在main()中未对gcd(x,y)类型(返回值的类型)进行说明。在主调函数main()中没有出现intgcd();声明语句。函数声明54函数声明被调函数的声明用户自定义函数的声明提示:在下列情况下可以省略函数声明当被调函数的定义出现在主调函数的前面时如果被调用函数的返回值是其它类型(非整型或字符型)函数定义和函数调用在同一个文件中,且函数定义在源程序中的位置在调用该函数之前55源程序:

floatmax-value(x,y,z)

floatx,y,z;{floatmax;max=x>y?x:y;max=max>z?max:z;return(max);}

main(){floata,b,c,max;

scanf(“%f%f%f”,&a,&b,&c);

max=max_value(a,b,c);

printf(“%f”,max);}871。c被调函数max_value()的定义放在主调函数main()之前,所以在main()中不再进行对max_value()函数的说明。函数声明56函数声明被调函数的声明用户自定义函数的声明提示:在下列情况下可以省略函数声明当全局声明被调函数时在所有函数定义之前(即在文件的开始处),对函数类型进行了说明在主调用函数中不再对被调函数(返回值)的类型进行声明这种方法最常用57样式:

floatmax_value();

voidcpy();

intcount();

main(){

voidcpy(s1,s2)

chars1[30],s2[20];{…

intcount(charstr,intn){…

}函数声明main()不必再声明所调用的函数类型。因此没有包含floatmax_value();voidcpy();intcount();的声明语句,即没有对这三个被调函数进行类型说明。58函数声明被调函数的声明用户自定义函数的声明提示:在下列情况下必须函数声明如果函数定义在源程序中的位置在调用该函数之后必须在调用该函数的函数中给出被调用函数的说明如果函数的定义与调用在两个不同的文件中不论函数返回值的类型是什么,在调用该函数时都必须给出函数声明59函数声明被调函数的声明提示函数的声明和函数的定义形式上十分相似,但两者上有本质上的不同的函数的定义是一个完整而独立的函数单元在程序中,函数的定义只能有一次函数首部后没有“;”函数的声明仅是对编译系统的一个说明是对已定义过的函数返回值的类型说明,以通知系统在本函数中所调用的函数是什么类型不包括函数体(或形参)是一个说明语句,必须以分号结束60函数声明被调函数的声明例main(){floata,b,c,max;

floatmax_value();/*对被调函数类型进行声明*/scanf(“%f%f%f”,&a,&b,&c);

max=max_value(a,b,c);

printf(“%f”,max);}

floatmax-value(x,y,z)

floatx,y,z;{floatmax;max=x>y?x:y;max=max>z?max:z;return(max);}被调函数定义在主调函数之后,所以在主调函数的声明部分对被调函数的类型(既返回值的类型)进行了说明。也可以写成:

floatmax_value

(float,float,float);61函数声明函数原型对被调函数的声明编译系统需知道被调函数有几个参数,各自是什么类型,而参数的名字是无关紧要的简化对被调函数的声明

上述方式称为函数的原型例floatmax_value(float,float,float);

/*仅声明形参的类型,不必指出形参的名*/通常将一个文件中需调用的所有函数原型写在文件的开始函数类型标识符函数名(形参类型1,形参类型2……);62函数声明小结写法上要注意函数定义的首部需要写出所有形参名并给出其对应的数据类型函数原型的主要目的在于声明函数返回值的类型以及函数期望接收的参数的个数、参数类型和参数顺序如果程序中没有某个函数的函数原型(没有说明),编译系统就会用第一次出现的这个函数(函数定义或函数调用)构造函数原型在缺省下编译系统假设函数返回类型为int而对函数参数类型不做任何假设常见错误和函数原型不匹配的函数调用会导致语法错误函数原型和函数定义不一致,也会产生错误63函数执行过程通过函数的调用实现函数的使用函数调用指定了被调用函数的名字和调用函数所需要的参数执行过程程序在主调函数执行过程中,执行到调用被调函数的语句时,程序将实际参数传递给形式参数执行被调函数的函数体语句,直到遇到return语句或“}”,结束被调函数的执行(带值)返回到主调函数执行主调函数的剩余语句部分64〖例〗]inti=10;

main(){intj=1;

j=fun();

printf(“%d”,j);

j=fun();

printf(“%d”,j);}

func(){intk=0;

k=k+i;

i=i+10;

return(k);}演示89。C执行过程:(1)主调程序main()顺序执行,第一个函数调用语句j=fun();处理“=”右边的调用函数fun()。(2)执行fun()函数体,k=k+i=10;i=20;(3)执行到return(k)语句,带回返回值(k=10)。(4)被调函数fun()的返回值赋给“=”左边的变量j,j=10;(5)执行库函数printf,打印j的值。(6)执行第二个函数调用语句j=fun();(7)执行fun()函数体,k=k+i=20;i=i+10=20;(8)执行到return(k)语句,带回返回值(k=20)。(9)被调函数fun()的返回值赋给“=”左边的变量j,j=20;(10)执行库函数printf(),打印j的值。函数执行过程程序设计基础(C语言)参数传递66参数传递函数之间的数据传递C语言的一个源程序文件可以由多个函数组成每个函数在功能上是独立的目地就是共同实现某一特定的功能,以解决某个具体的实际问题函数与函数之间通常要传递数据和计算结果C语言中采用三种方式进行数据传递参数传递实参与形参一一对应方法在主调函数与被调函数之间传递多个数据返回值传递被调函数返回主调函数一个结果值全局变量传递在一个函数内使用其他函数中的某些变量的结果67参数传递形参与实参形参是函数定义时由用户定义的形式上的变量定义函数时函数名后()内的变量列表形参与函数体内定义的其它变量一样在函数体内引用这些变量在未调用函数之前并不实际占用内存实参是函数调用时,主调函数为被调函数提供的原始数据调用函数时给该函数形参具体指定的值是常量、表达式或变量例如:

main()

{….a=max(num1,num2);

…..}intmax(intx,inty)68参数传递参数传递方式——"值传递”含义在调用函数时,将实参变量的值取出来,复制给形参变量C语言中的实参可以是一个表达式调用时先计算表达式的值,再将结果(值)复制到形参对应的存储单元中在函数内部使用从实参中复制来的值进行处理形参是函数的局部变量仅在函数内部才有意义不能用它来传递函数的结果一旦函数执行结束形参存储单元所保存的值不再保留69参数传递“传值”特点数据在主调函数和被调函数中占用不同的存储空间在函数内部对形参的任何操作,其结果只能影响形式参数的值,而不影响实际参数的值可以避免被调用函数的操作对调用函数中的变量可能产生的副作用此种方式只能实现外部数据向函数内部的传递,而不能实现函数内部数据的传出70例:

voidchange(intk){printf(“2·k=%d\n”,k);

k=k+10;printf(“4·k=%d\n”,k);}

main()

{inti;

i=10;

printf(“1·i=%d\n”,i);

change(i);

printf(“3·i=%d\n”,i);}实参i1010形参k10(调用开始时)20(调用结束时)调用之前参数传递“传值”71例:分析下面程序结果

main(){inta,b;voidp(int,int);a=5;b=8;p(a,b);p(a+b,a);p(a/b,b);}voidp(intx,inty){y=x+y;printf("%d,%d\n",x,y);}

则程序的执行结果为:A.5,13B.5,13C.5,13D.5,1313,1818,518,518,230,81,131,141,13参数传递“传值”72例:求100~200之间的全部素数之和#include“math.h”main(){intm,sum=0;

for(m=101;m<=200;m=m+2)

sum+=sum(m);

printf(“%d\n”,s);}

intsum(intm){inti,k;

k=sqrt(m);

for(i=2;i<=k;i++)

if(m%i==0)return(0);

return(m);}参数传递“传值”73源程序:

#include<stdio.h>main(){intk=2,n=0;

do{if(isprime(k)&&isprime(k+2))

{n+=1;

printf(“%d,%d”,k,k+2);}k=k+1;

}while(n<15);

}isprime(inta);

{intk,j;j=1;k=2;

while((k<=a/2)&&j)

{if(a%k==0)j=0;

elsek=k+1;}return(j);

}参数传递例题孪生素数是指两个相差为2的素数,例如:3和5,5和7,11和13等。编程实现输出15对孪生素数。74源程序:

main()

{intx,y;

x=3;y=5;

printf(“beforeswapx=%d,y=%d\n”,x,y);

swap(x,y);/*用变量x和y作为实际参数调用函数*/

printf(“afterswapx=%d,y=%d\n”,x,y);

}

swap(intm,intn)

{inttemp;/*借助临时变量交换两个形参变量m和n的值*/

temp=m;/*①*/

m=n;/*②*/

n=temp;/*③*/

printf("inswapm=%d,n=%d\n",m,n);

}参数传递例题若在主函数中变量x=3,y=5,编写一个函数交换主函数中两个变量的值,使变量x=5,y=3。

“传值”beforeswapx=3,y=5

inswapm=5,n=3

afterswapx=3,y=575参数传递“传址”传递地址在值传递方式下,每个形式参数仅能传递一个数据当需要在函数之间传递大量数据时,值传递方式显然不适用将数据的存储地址作为实参传递给被调函数的形参允许被调用函数修改原始的变量值要求形参的数据类型应是指针类型76参数传递“传址”特点处理数据在主调函数和被调函数中占用相同的存储空间形参和实参所指向的地址是同一个地址对形参的操作会直接影响到实参的结果此种方式即可以实现外部数据向函数内部的传递,也可以实现加工后的数据从函数内部向主调函数的传递详细内容参见指针77参数传递函数参数提示形参在被调函数中定义,实参在主调函数中定义形参是形式上的定义时编译系统并不为其分配存储空间函数调用时,临时分配存储空间,接受并处理实参函数调用结束,形参被释放(数据消失)实参可以是变量名或表达式必须在函数调用之间有确定的值实参与形参必须类型相同,个数相等,一一对应当实参之间有联系时,不同的编译系统下实参的求值顺序不同VC是从右向左78参数传递数组作函数参数两种方式数组中的元素作函数的参数数组名作函数的参数例:inta[5];a[2]intxapaint*pa;或intb[5];a79参数传递数组作函数参数数组元素作函数的参数可以采用传递普通变量一样的方式以单个元素的方式实现数组元素的传递“复制数据”的方法由于形参是在函数定义时定义,并无具体的值,因此数组元素只能在函数调用时,作函数的实参当用数组中的元素作函数的实参时必须在主调函数内定义数组,并赋值实参与形参之间是“值传递”的方式80参数传递数组作函数参数数组元素作函数的参数例:求一维数组a[4]的所有元素之和数组元素作实参floatsumall(floata,floatb,floatc,floatd);{

return(a+b+c+d);}

main(){floatsum;

staticfloata[4]={1,2,3,4};

sum=sumall(a[0],a[1],a[2],a[3]);

printf(“sum=%f\n”,sum);}演示8B。C在调用sumall函数时,将数组元素a[0]…a[3]作为实参把值传递给sumall函数的a,b,c,d的四个形参,是单向的按值传递。81参数传递数组作函数参数数组名作参数数组名作函数的参数,必须遵循以下原则参数形式如果形参是数组名,则实参必须是实际的数组名如果实参是数组名,则形参可以是同样维数的数组名或指针数组定义要在主调函数和被调函数中分别定义数组形参数组可以不指明长度82参数传递数组作函数参数数组名作参数提示C语言允许将整个数组作为函数的参数进行传递数组名代表了该数组在内存中的首地址采用的是按址传递方式调用方式只需将数组名作为参数直接调用函数即可,无须使用下标实参数组名将该数组的起始地址传递给形参数组,两个数组共享一段内存单元83参数传递数组作函数参数数组名作参数例:分析程序的执行过程分析调用时,实参数组将首地址string赋值给形参数组str两个数组共同占用相同的内存单元,共享数组中的数据string[0]与str[0]代表同一个元素#include<stdio.h>

print(charstr[])

{printf("%s",str);

}

main()

{charstring[20]="CProgramming";

print(string);/*数组名做函数的实参*/

}84参数传递数组作函数参数演示:传递整个数组和传递一个数组元素之间的差别#include<sdtio.h>#defineSIZE5

voidmodifyarray(int[],int);

voidmodifyelement(int);main(){inta[SIZE]={0,1,2,3,4};inti;pritnf(“\nThevaluesoftheoriginalarrayare:\n”);for(i=0;i<=SIZE-1;i++)printf(“%3d”,a[i]);printf(“\n”);

modifyarray(a,SIZE);/*以传址方式传递数组a*/pritnf(“Thevaluesosthemodifiedarrayare:\n”);

85for(i=0;i<=SIZE-1;i++)printf(“%3d”,a[i]);printf(“\nThevaluesofa[3]is%3d\n”,a[3]);

modifyelement(a[3]);printf(“Thevaluesofa[3]is%3d\n”,a[3]);}

voidmodifyarray(intb[],intsize){intj;for(j=0;j<=size-1;j++)b[j]*=2;}

voidmodifyelement(intx){printf(“Velueinmodifyelementis%3d\n”,x*=2);}

参数传递86参数传递数组作函数参数例题【例】求任意输入10个数的平均值。(数组名作实参)

#include“stdio.h”main(){inti;

floata[10],ave;

floataver(floata[10]);

for(i=0;i<10;i++)

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

ave=aver(a);

printf(“\naver=%6.2f\n”,ave);}

floataver(floatb[10]){inti;floats=0.0,ave;

for(i=0;i<10;i++)

s+=b[i];

ave=s/10;

return(ave);}87参数传递数组作函数参数例题下面程序的输出结果是().

#include<stdio.h>intfun(intx[],intn){inti,s=1;for(i=0;i<=n;i++)s*=x[i];returns;}main(){inta[]={1,2,3,4,5,6};intx=fun(a,4);printf(“%d”,x);}A.24B.120C.720D.5本题主要测试数组在函数之间传递的用法。在函数间传递数组时,通常传递的是数组的首地址。由于数组元素是连续存放的,因此可以根据该地址找到数组的所有的元素。由于传递数组的长度为4,因此函数

fun中的计算只包括元素1,2,3,4,5,函数返回的值是1*2*3*4*5=120。所以输出是120。88参数传递数组作函数参数例题编写一个函数,分别求两个浮点数数组元素的平均值。并在主调函数中输出floataverage(arrary,n)

intn;

floatarrary[];{inti;

floataver,sum=0.0;

for(i=0;i<n;i++)

sum+=arrary[i];

aver=sum/n;

return(aver);}定义形参时未指明数组大小,而且引进一个参数n,以便两次调用average函数时,两个实参数组的长度可以先后传递给n,从而在average函数体中能分别访问两个数组的所有元素.89参数传递数组作函数参数例题编写一个函数,分别求两个浮点数数组元素的平均值。并在主调函数中输出main(){floata[8],b[9];

inti;

for(i=0;i<8;i++)

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

for(i=0;i<9;i++)

scanf(“%f”,&b[i]);

printf(“aver=%7.2f\n”,average(a,8));

printf(“aver=%7.2f\n”,average(b,9));}程序设计基础(C语言)参数的嵌套调用91函数嵌套调用嵌套调用C语言中的函数定义是平行的函数间没有主从关系函数不允许进行函数的嵌套定义在一个函数体中再定义一个新的函数函数之间的调用可以是任意的函数允许嵌套调用允许在一个函数体内再调用其他函数函数嵌套定义指一个函数在被其它函数调用的过程中,本身还被允许调用另一个函数在函数体中再调用其它函数92函数嵌套调用嵌套过程函数的嵌套调用为自顶向下、逐步求精及模块化的结构设计提供了有利的支持如果在实现一个函数的功能时需要用到其它函数的功能,就采用函数的嵌套调用main(){…num1();

…}num1(){…num2();

…}num2(){

}93#include<stdio.h>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(“%d\n”

,d);}intdif(intx,inty,intz){return(max(x,y,z)-

min(x,y,z));}函数嵌套调用嵌套过程例:求三个数最大与最小的差值分析在这个程序中共定义三个函数dif()求差值max()求最大数min()求最小数在调用dif()时需要调用max()和min()分别求出最大和最小94intmin(intx,inty,intz){intr;

if(x>y){if(y<z)r=y;

elser=z;}

else{if(x<z)r=x;

elser=z;}

return(r);}intmax(intx,inty,intz){intr;

if(x>y){if(x>z)r=x;

elser=z;}

else{if(y>z)r=y;

elser=z;}

return(r);}函数嵌套调用95函数嵌套调用嵌套过程例:编写程序输出20以内的全部素数,并计算20以内全部素数之积与全部素数之和的商96#include<stdio.h>#include<math.h>intisprime(int);

main(){inti,a,s;

floatb,c;

intadd(int);

floatm

温馨提示

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

评论

0/150

提交评论