C语言第7章函数2_第1页
C语言第7章函数2_第2页
C语言第7章函数2_第3页
C语言第7章函数2_第4页
C语言第7章函数2_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

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

文档简介

11第7章用函数实现模块化程序设计2

本章要点函数的概念函数的定义与调用函数的嵌套调用数组作为函数参数局部变量和全局变量3知识回顾一、函数调用的一般格式说明:(1)实参表中列出实际“传递”到函数中的参数,参数的个数、次序应当与形参表所列的一致,中间用逗号分隔。(2)每个实参都是一个有确定值的表达式,表达式的类型必须与对应形参的类型兼容。(3)如果函数无形参,则实参表也是空的,但括号仍要有。

函数名(实参表)

4知识回顾二、return语句功能

1)返回表达式的值 2)结束被调函数的执行,并将控制转移到主调函数的调用处(断点)继续执行。使用形式

1)不返回值:return;2)返回值:return表达式;5知识回顾三、函数调用方式1.函数调用语句把函数调用单独作为一个语句

如printf_star();这时不要求函数带回值,只要求函数完成一定的操作。6知识回顾2.函数表达式函数调用出现在另一个表达式中

如c=max(a,b);这时要求函数带回一个确定的值以参加表达式的运算。3.函数参数函数调用作为另一函数调用时的实参

如m=max(a,max(b,c));其中max(b,c)是一次函数调用,它的值作为max另一次调用的实参。7知识回顾四、函数的参数传递

1、值传递(单向)参数形式:实参用表达式,形参用变量。

2、地址传递(双向)参数形式:实参用地址常量或变量,形参用地址常量或变量。8本节重点掌握内容一、数组作为函数参数二、局部变量和全局变量9一、数组作为函数参数一、问题的提出

例7.1编写一个函数实现下述功能:返回4个单精度实数中的最大值。分析:①函数名max。②函数返回值类型为float。③形式参数个数:4个。④函数体:选择结构。10一、数组作为函数参数

#include<stdio.h>floatmax(float

w,float

x,float

y,floatz){floatm;

if(w>x)m=w;elsem=x;

if(y>m)m=y;

if(z>m)m=z;returnm;}voidmain(){floata[4]={3,8,11,9},max;max=max(a[0],a[1],a[2],a[3]);

printf(“max=%d”,max);}值传递程序分析:①执行时需开辟4个float类型空间。②必须使用多个选择结构。

如果求100个实数的最大值呢?

能否利用数组传递大批量数据呢?11一、数组作为函数参数

#include<stdio.h>floatmax(floatarray[],intn){floatm=array[0];for(inti=1;i<n;i++){if(m<array[i])m=array[i];returnm;}voidmain(){floata[4]={3,8,11,9},max;max=max(a,4);

printf(“max=%d”,max);}若有floata[100],且已正确赋值,则可使用max=max(a,100);求得100个实数中的最大值。12一、数组作为函数参数数组可以作为函数的参数使用,进行数据传送。数组用作函数参数有两种形式:(1)把数组元素作为实参使用;(2)把数组名作为函数的形参和实参使用。1、数组元素作函数实参数组元素与普通变量并无区别。因此它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。

13一、数组作为函数参数例7.2判别一个整数数组中各元素的值,若大于0则输出该值,若小于等于0则输出0值。voidnzp(intv){if(v>0)printf("%d",v);elseprintf("%d",0);}main(){inta[5],i;

printf("input5numbers\n");

for(i=0;i<5;i++){scanf("%d",&a[i]);

nzp(a[i]);}}定义一个无返回值函数nzp,并说明其形参v为整型变量输入数组各元素,每输入一个就以该元素作实参调用一次nzp函数,即把a[i]的值传送给形参v,供nzp函数使用。

输入:3507-2根据v值输出相应的结果

输出:3507014一、数组作为函数参数2、数组名作函数形参函数定义的一般格式

返回值类型

函数名

(形参定义表

)//函数头{

语句序列;//函数体

[return表达式;]}(数组类型数组名[]

,int

元素个数,其他形参)15一、数组作为函数参数2、数组名作函数形参

例:floatmax(floatarray[],int

n){floatm=array[0];for(inti=1;i<n;i++)

if(m<array[i]) m=array[i];

returnm;}函数名形参返回值类型函数体局部变量定义函数头返回值语句16一、数组作为函数参数3、数组名作函数实参函数调用的一般格式函数名

(实参数组名,实际元素个数,其他实参)voidmain(){floata[4]={3,8,11,9},ma;ma=max(a,4);printf(“max=%f”,ma)}17一、数组作为函数参数4、数组名作函数参数时的参数传递

参数形式:实参用数组名,形参用数组名[]函数调用时,把实参数组的首地址传递给形参数组,这样两个数组就共同占用同一段内存空间,即“传地址”。相当于形参数组名通过形实结合成为实参数组的一个别名,所以形参数组的改变直接影响到实参数组。双向传递:实参

形参

18一、数组作为函数参数

例7.3编写一个函数实现下述功能:把数组下标从0到n的元素值置为0。输入输出由主函数完成。分析:①程序由两个函数构成:main()+clear()。②主调函数main()里实现输入原数组,调用clear()进行处理,并输出改变后的数组。③被调函数clear()实现相应元素清0功能,即把相应元素赋值为0。19一、数组作为函数参数

#include<stdio.h>voidclear(int

arr[],intn);voidmain(){inta[10],i,j;

printf("请输入10个整数:\n");

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

scanf("%d",&a[i]);

printf("原数组为:\n");

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

printf("%d",a[i]);

printf("\n请输入要清0元素的最大下标:");

scanf("%d",&j);

clear(a,j);

printf("改变后的数组是:\n");

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

printf("%d",a[i]);}voidclear(int

arr[],intn){inti;

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

arr[i]=0;}20一、数组作为函数参数

#include<stdio.h>voidclear(int

arr[],intn);voidmain(){inta[10],i,j;

printf("请输入10个整数:\n");

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

scanf("%d",&a[i]);

printf("原数组为:\n");

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

printf("%d",a[i]);

printf("\n请输入要清0元素的最大下标:");

scanf("%d",&j);

clear(a,j);

printf("改变后的数组是:\n");

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

printf("%d",a[i]);}voidclear(int

arr[],intn){inti;

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

arr[i]=0;}a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]aij申请变量调用前1234567891010621一、数组作为函数参数

#include<stdio.h>voidclear(int

arr[],intn);voidmain(){inta[10],i,j;

printf("请输入10个整数:\n");

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

scanf("%d",&a[i]);

printf("原数组为:\n");

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

printf("%d",a[i]);

printf("\n请输入要清0元素的最大下标:");

scanf("%d",&j);

clear(a,j);

printf("改变后的数组是:\n");

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

printf("%d",a[i]);}voidclear(int

arr[],intn){inti;

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

arr[i]=0;}12345a[0]a[1]a[2]a[3]a[4]678910a[5]a[6]a[7]a[8]a[9]a10i6j调用时arrni600000007返回前一、数组作为函数参数

#include<stdio.h>voidclear(int

arr[],intn);voidmain(){inta[10],i,j;

printf("请输入10个整数:\n");

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

scanf("%d",&a[i]);

printf("原数组为:\n");

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

printf("%d",a[i]);

printf("\n请输入要清0元素的最大下标:");

scanf("%d",&j);

clear(a,j);

printf("改变后的数组是:\n");

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

printf("%d",a[i]);}voidclear(int

arr[],intn){inti;

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

arr[i]=0;}00000a[0]a[1]a[2]a[3]a[4]008910a[5]a[6]a[7]a[8]a[9]a10i6jarr6n7i返回后一、数组作为函数参数说明:

用数组名作函数参数与用数组元素作实参有几点不同1、用数组元素作实参时,并不要求函数的形参也是下标变量,对数组元素的处理是按普通变量对待的。用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误一、数组作为函数参数说明:

用数组名作函数参数与用数组元素作实参有几点不同2、在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。在函数调用时是把实参变量的值赋予形参变量,发生的值传送。在用数组名作函数参数时,不是进行值的传送,是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。一、数组作为函数参数a为实参数组,类型为整型。a占有以2000为首地址的一块内存区。b为形参数组名。当发生函数调用时,进行地址传送,把实参数组a的首地址传送给形参数组名b,于是b也取得该地址2000。于是a,b两数组共同占有以2000为首地址的一段连续内存单元。例如a[0]和b[0]都占用2000和2001单元,当然a[0]等于b[0]。类推则有a[i]等于b[i]。一、数组作为函数参数说明:

用数组名作函数参数与用数组元素作实参有几点不同3、在变量作函数参数时,值传送是单向的,即只能从实参传向形参,不能从形参传回实参。形参的初值和实参相同,而形参的值发生改变后,实参并不变化,两者的终值是不同的。而当用数组名作函数参数时,实际上形参和实参为同一数组,因此当形参数组发生变化时,实参数组也随之变化。27一、数组作为函数参数

例7.4有一个一维数组score,内放10个学生成绩,求平均成绩。分析:①程序由两个函数构成:main()+average()。②用函数average()求平均成绩,用数组名作为函数实参,形参也用数组名。③在average()函数中引用各数组元素,求平均成绩并返回main()函数28一、数组作为函数参数#include<stdio.h>intmain(){floataverage(floatarray[10]);floatscore[10],aver;inti;

printf("input10scores:\n");

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

scanf("%f",&score[i]);

printf("\n");aver=average(score);printf("%5.2f\n",aver);return0;}

floataverage(floatarray[10]){inti;floataver,sum=array[0];

for(i=1;i<10;i++)sum=sum+array[i];aver=sum/10;

return(aver);}定义形参数组相当于score[0]相当于score[i]29一、数组作为函数参数

例7.5有两个班级,分别有35名和30名学生,调用一个average函数,分别求这两个班的学生的平均成绩。分析:需要解决怎样用同一个函数求两个不同长度的数组的平均值的问题①程序由两个函数构成:main()+average()。②定义average()函数时不指定数组的长度,在形参表中增加一个整型变量n。③从主函数把数组实际长度从实参传递给形参n。30一、数组作为函数参数#include<stdio.h>intmain(){floataverage(floatarray[],intn);floatscore1[5]={98.5,97,91.5,60,55};floatscore2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5};printf(“%6.2f\n”,average(score1,5));printf(“%6.2f\n”,average(score2,10));return0;}31一、数组作为函数参数floataverage(floatarray[],intn){inti;floataver,sum=array[0];

for(i=1;i<n;i++)sum=sum+array[i];aver=sum/n;

return(aver);}调用形式为average(score1,5)时相当于score1[i]相当于score1[0]相当于532一、数组作为函数参数floataverage(floatarray[],intn){inti;floataver,sum=array[0];

for(i=1;i<n;i++)sum=sum+array[i];aver=sum/n;

return(aver);}调用形式为average(score2,10)时相当于score2[i]相当于score2[0]相当于10一、数组作为函数参数说明:用数组名作为函数参数时还应注意以下几点:

1、形参数组和实参数组的类型必须一致,否则将引起错误。

2、形参数组和实参数组的长度可以不相同,因为在调用时,只传送首地址而不检查形参数组的长度。当形参数组的长度与实参数组不一致时,虽不至于出现语法错误(编译能通过),但程序执行结果将与实际不符,这是应予以注意的。一、数组作为函数参数说明:用数组名作为函数参数时还应注意以下几点:

3、在函数形参表中,允许不给出形参数组的长度,或用一个变量来表示数组元素的个数。例如可以写为:

voidnzp(inta[])或voidnzp(inta[],intn)

注:voidnzp(int

a[n],intn)

其中形参数组a没有给出长度,而由n值动态地表示数组的长度。n的值由主调函数的实参进行传送。×35一、数组作为函数参数

例7.6用选择法对数组中10个整数按由小到大排序。(所谓选择法:就是先选择10个数中最小的数与a[0]对换;再选择a[1]到a[9]中最小的数与a[1]对换……每比较一轮,找出一个未经排序的数中最小的一个。)分析:①程序由两个函数构成:main()+sort()。②主调函数main()里实现输入原数组,调用sort()进行处理,并输出改变后的数组。③被调函数sort()实现相应排序功能,即把相应元素按从小到大顺序排序。一、数组作为函数参数a[0]a[1]a[2]a[3]a[4]36194

16394

1

3694

1

3

496

1

3

4

69小到大排序37一、数组作为函数参数#include<stdio.h>intmain(){voidsort(int

array[],intn);

inta[10],i;

printf("enterarray:\n");

for(i=0;i<10;i++)scanf("%d",&a[i]);sort(a,10);

printf("Thesortedarray:\n");

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

printf("\n");return0;}

38一、数组作为函数参数voidsort(int

array[],int

n){int

i,j,k,t;

for(i=0;i<n-1;i++){k=i;

for(j=i+1;j<n;j++)

if(array[j]<array[k])k=j; t=array[k];

array[k]=array[i];

array[i]=t; }}在array[i]~array[9]中,选出最小数39一、数组作为函数参数5、多维数组名作函数参数函数定义的一般格式

返回值类型

函数名

(形参定义表

)//函数头{

语句序列;//函数体

[return表达式;]}(数组类型数组名[m][n])或(数组类型数组名[][n])40一、数组作为函数参数

例7.7求一个3×4的矩阵中所有元素的最大值。分析:①程序由两个函数构成:main()+max_value()。②主调函数main()里实现输入原数组,调用max_value()进行处理,并输出最大值。③被调函数max_value()实现求最大值功能,并将最大值返回给主调函数。41一、数组作为函数参数#include<stdio.h>intmain(){int

max_value(intarray[][4]);

inta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};

printf(“Maxvalueis%d\n”,max_value(a));return0;}可以省略不能省略42一、数组作为函数参数int

max_value(intarray[][4]){int

i,j,max;max=array[0][0];for(i=0;i<3;i++)

for(j=0;j<4;j++)if(array[i][j]>max)max=array[i][j];return(max);}43本节重点掌握内容一、数组作为函数参数二、局部变量和全局变量44二、局部变量和全局变量从变量的作用域来认识变量

——局部变量和全局变量可引用变量的范围45二、局部变量和全局变量1、局部变量

(1)定义:定义在函数内或在{}内的变量,称为局部变量。(2)有效范围:在所定义的函数、复合语句中。变量的作用范围仅仅局限在从变量定义处开始、到变量定义所在的那个函数或复合语句结束。函数的形式参数为局部变量。46二、局部变量和全局变量1、局部变量例:分析下面变量的作用域

floatf1(inta){

int

b,c;…}intf2(intx,inty){

int

b,c,i,j;…}a,b,c有效x,y,b,c,i,j有效47二、局部变量和全局变量

intmain(){

int

m,n;{

intk…}...}1、局部变量例:分析下面变量的作用域

m,n有效k有效48二、局部变量和全局变量1、局部变量

说明:(1)形参是局部变量(2)main函数的变量也是局部的(3)不同函数中变量的名字可以相同(4)复合语句内可以定义变量49二、局部变量和全局变量1、局部变量例:

func(inta,charch)

{

intb=1,c=2;

floatf;... a=5a=3{inta,b=3;

a=b+c;

printf("a=%d\n",a);}a=b+c;

printf("a=%d\n",a);

}Why?局部变量的作用域举例—交换两个变量的值51二、局部变量和全局变量2、全局变量

(1)定义:在函数之外定义的变量,称为全局变量。全局变量又称为外部变量。

(2)有效范围:从变量定义处开始到该源文件结束处。说明:如果在同一源文件中,外部变量和局部变量同名,则在局部变量的作用范围内,外部变量不起作用。52二、局部变量和全局变量2、全局变量例:

intp=1,q=5;/*外部变量*/f1(inta)/*定义函数*/{intb,c;……}charc1,c2;/*外部变量*/f2(inta,intb)/*定义函数*/{…….}main(){intm,n……}c1,c2的作用范围p,q的作用范围输入2,5?结论:全局变量在任何函数内可见函数exch()改一下,结果如何?输入2,5?a=3,b=7?结论:如果函数中的局部变量和全局变量同名,在函数范围内,局部变量可见。55一、数组作为函数参数

例7.8求10个学生的平均分,最高分和最低分。分析:调用一个函数可以得到一个函数返回值,现在希望通过函数调用能得到3个结果。可以利用全局变量来达到此目的。56一、数组作为函数参数floatMax=0,Min=0;voidmain(){floataverage(floatarray[],intn);floatavg,score[10];

inti;

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

scanf("%f",&score[i]);

avg=average(score,10);

printf(“max=%6.2f,min=%6.2f,avg=%6.2f\n",Max,Min,avg);}57一、数组作为函数参数floataverage(floatarray[],intn){inti;floataver,sum=array[0];Max=Min=array[0];

for(i=1;i<n;i++){if(array[i]>Max)Max=array[i];

if(array[i]<Mix)Mix=array[i];sum+=array[i];}aver=sum/n;returnaver;}avgscore10MaxMinaverarray10MaxMinmain函数average函数全局变量MaxMin58二、局部变量和全局变量2、全局变量

说明:全局变量给程序设计带来诸多弊端:(1)降低程序的清晰度(2)降低函数的灵活性(3)降低存储空间的利用率适当使用!59总结一、数组作函数参数1、数组元素作函数实参2、数组名作函数形参3、数组名作函数实参

4、多维数组名作函数参数二、局部变量和全局变量60思考题

1、编写一个函数实现下述功能:求数组所有元素的和。输入输出由主函数完成。

2、编程实现:从键盘输入10个整数,然后统计并输出其中负数的个数。要求定义并使用计算数组中负数个数的函数int

温馨提示

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

评论

0/150

提交评论