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

下载本文档

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

文档简介

第7章函数教学目标掌握自定义函数的一般结构及函数的定义方法;掌握函数声明、函数调用的一般方法;掌握形参、实参、函数原型等重要概念;熟悉数组作函数的参数时函数的定义和调用方法;熟悉函数嵌套、函数递归的概念;能定义和使用嵌套函数、递归函数;了解局部变量、全局变量和变量的存储类型的概念;熟悉auto型和static型局部变量的特点和用法。1第7章函数教学目标1第7章函数知识点函数的定义与调用;函数调用时的数据传递方法;数组作为函数参数;函数的嵌套调用和递归调用;局部变量与全局变量的作用域;动态存储变量和静态存储变量的生存期。重点:函数的定义与调用;函数调用时的数据传递方法。难点:函数调用时的数据传递方法;递归函数的设计;变量的作用域和生存期。2第7章函数知识点27.1函数概述函数是构成C程序的基本构件。C语言的程序是由一个主函数或若干个函数组成的。但编译单位是源程序文件,而不是函数。C程序执行是从main函数(主函数)开始,在main函数中结束,不管main函数的位置如何。所有的函数独立定义,main()函数可以调用任意其它函数,其它函数之间可以相互调用,但任何函数都不能调用main()函数。37.1函数概述函数是构成C程序的基本构件。C语言的程序是函数的分类标准函数(库函数):由系统提供,如printf()自定义函数:由用户自己定义,解决特定的问题有参函数:主调函数与被调函数之间有参数传递如printf()无参函数:主调函数与被调函数之间无参数传递如getchar()有返回值函数:被调函数返回一个值给主调函数如getchar()无返回值函数:被调函数不带回值给主调函数如printf()4函数的分类标准函数(库函数):由系统提供,如printf7.2函数定义与函数调用函数定义:

函数调用:

函数定义时函数名后的括号中的变量叫形式参数,简称形参

两个实际参数函数调用时函数名后的括号中的参数叫实际参数,简称实参

函数值两个形式参数57.2函数定义与函数调用函数定义:函数调用:函数定义一、函数定义与函数调用函数定义的格式:[函数类型]函数名([形参及形参声明表列]){内部变量定义和声明部分执行语句}函数定义后,并不被执行,只有当调用函数时,程序才转到函数去执行。函数调用的格式:函数名([实参表列])6一、函数定义与函数调用函数定义的格式:61.无参无返回值函数的定义与调用#include<stdio.h>voidpstar(){ printf("****************\n");}voidmain(){inti;for(i=1;i<=10;i++)pstar();}函数类型void(“空类型”)表示无返回值

函数名无参数函数定义以语句方式调用无返回值函数函数定义71.无参无返回值函数的定义与调用#include<s2.有参无返回值函数的定义与调用#include<stdio.h>voidpstar(intn){intk;/*形参在函数体内不能再定义*/for(k=1;k<=n;k++)printf("*");printf("\n");}voidmain(){inti;for(i=1;i<=10;i++)pstar(20);

}形参k

被声明为int型

函数定义实参2082.有参无返回值函数的定义与调用#include<s3.有返回值函数的定义与调用#include<stdio.h>intmax(intx,inty){intz;z=x>y?x:y;return(z);}voidmain(){inta,b,c;scanf("%d%d",&a,&b);c=max(a,b);/*将函数的返回值赋给变量c*/

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

}int型函数(int可缺省),表示函数返回值为整型

函数定义return后的括号可以不要

注意:程序可直接写为:return(x>y?x:y);93.有返回值函数的定义与调用#include<std有返回值函数的定义与调用上题程序可修改为:#include<stdio.h>intmax(intx,inty){return(x>y?x:y);}voidmain(){inta,b,c;scanf("%d%d",&a,&b);

printf(“Maxis%d\n”,max(a,b));

}将max函数的返回值作为printf函数的参数函数定义10有返回值函数的定义与调用上题程序可修改为:将max函数的返回二、函数的参数一、形式参数与实际参数对无参函数,形参表列与实参表列均为空,但括号不能省略,如fun()。对有参函数,实参与形参应个数相等,顺序对应,类型一致或赋值相容。定义函数时形参不占用存储单元,只有在调用函数期间才给形参分配存储单元,并将实参的值传递给形参。函数调用结束,形参所占用存储单元也被释放。11二、函数的参数一、形式参数与实际参数11函数的参数若形参是变量名,实参可以是常量、变量或表达式,如函数调用max(3,a+b);若形参是数组名,实参是数组名,或者数组指针。注:实参对形参的数据传递是“单向值传递”:实参的值传递给形参,而形参的值不会传回给实参。12函数的参数若形参是变量名,实参可以是常量、变量或表达式,如函三、函数的返回值函数返回值的获得:由return语句获得。函数返回值的类型:取决于函数的类型。例:floatmax(intx,inty){return(x>y?x:y);}问:函数返回值是int还是float型?答:float将无返回值的函数类型定义为void。13三、函数的返回值函数返回值的获得:由return语句获得四、函数的调用方式函数调用的格式:函数名([实参表列])函数调用的三种方式:函数语句:把函数调用作为一个语句,这种调用方式不使用函数的返回值,是无返回值函数的调用方式。

如,pstar(20);14四、函数的调用方式函数调用的格式:函数名([实参表列])函数的调用方式函数表达式:把函数调用作为表达式的一部分,这种调用方式使用函数返回的函数值,是有返回值函数的调用方式。

如,c=max(a,b);函数参数:把函数调用作为一个实参进行函数调用,这种调用方式也要使用函数的返回函数值,也是有返回值函数的调用方式。

如,printf("Maxis%d\n",max(a,b));15函数的调用方式函数表达式:把函数调用作为表达式的一部分,这举例判断素数函数1

(无返回值函数)#include<stdio.h>#include<math.h>voidprime(intm){intj,k;k=sqrt(m);for(j=2;j<=k;j++)if(m%j==0)break;if(j>k)printf("%disaprimenumber\n",m);elseprintf("%disnotaprimenumber\n",m);}main(){intn;scanf("%d",&n);prime(n)}为了明确表示无返回值用void定义函数类型

16举例判断素数函数1

(无返回值函数)#include举例判断素数函数2

(有返回值函数)#include<stdio.h>#include<math.h>prime(intm){intj,k,f;k=sqrt(m);for(j=2;j<=k;j++)if(m%j==0)break;if(j>k)f=1;/*返回1表示m是素数*/elsef=0;/*返回0表示m不是素数*/return(f);}voidmain(){intn;scanf("%d",&n);if(prime(n)==1)printf(“%disaprimenumber\n",n);elseprintf("%disnotaprimenumber\n",n);}prime(n)17举例判断素数函数2

(有返回值函数)#include五、函数调用的条件1、被调函数是库函数或已经存在的自定义函数;2、若被调函数是库函数,一般需在文件开头将其头文件#include到本文件;3、若被调函数是自定义函数,一般应在调用前进行函数原型声明,声明的格式是:函数类型函数名(形参类型表列);或者:函数类型函数名(形参名及其类型表列);举例:intmax(int,int);

或:intmax(intx,inty);一个例外:若被调函数定义在前、调用在后,则可不加函数原型声明。

18五、函数调用的条件1、被调函数是库函数或已经存在的自定义函函数原型声明方式1、在主调函数内部声明;2、在函数的外部声明,一般放在所有函数定义之前,即文件开头。19函数原型声明方式1、在主调函数内部声明;19函数原型声明举例#include<stdio.h>voidmain(){inta,b;floatz;

scanf("%d%d",&a,&b);z=average(a,b);printf("a=%d,b=%d,c=%.2f\n",a,b,z);}floataverage(inta,intb)inta,b;{floatc;c=(a+b)/2.0;return(c);}函数调用在前

在主调函数内部声明floataverage(int,int);函数定义在后

20函数原型声明举例#include<stdio.h>函数调函数原型声明举例#include<stdio.h>

voidmain(){inta,b;floatz;scanf("%d%d",&a,&b);z=average(a,b);printf("a=%d,b=%d,c=%.2f\n",a,b,z);}floataverage(inta,intb)inta,b;{floatc;c=(a+b)/2.0;return(c);}函数调用在前

文件开头,外部声明floataverage(int,int);函数定义在后

21函数原型声明举例#include<stdio.h>函数调函数原型声明举例#include<stdio.h>

floataverage(inta,intb){floatc;c=(a+b)/2.0;return(c);}voidmain(){inta,b;floatz;scanf("%d%d",&a,&b);z=average(a,b);printf("a=%d,b=%d,c=%.2f\n",a,b,z);}函数定义在前函数定义在前,函数调用在后;无需声明函数调用在后

22函数原型声明举例#include<stdio.h>函数定7.3函数调用中的参数传递简单变量作为函数参数指针变量作为函数参数数组作为函数参数237.3函数调用中的参数传递简单变量作为函数参数231、简单变量作为函数参数若形参是变量名,实参可以是常量、变量或表达式。实参对形参变量的传递是“单向数值传递”:实参的值传递给形参,而形参的值不会传回给实参。改变形参的值不会使实参的值发生变化实参形参值241、简单变量作为函数参数若形参是变量名,实参可以是常量、变量举例对两个数按降序排列(1)例:以下程序能实现a和b两个变量的交换吗?voidswap(intx,inty){intt;t=x;x=y;y=t;}#include<stdio.h>voidmain(){inta,b;scanf(”%d,%d”,&a,&b);if(a<b)swap(a,b);printf(”%d,%d\n”,a,b);}这样的程序无法实现a和b两个变量的交换!

35abxyt3535325举例对两个数按降序排列(1)例:以下程序能实现a和b两2、指针变量作为函数参数指针作为函数参数:

形参指针也指向实参指针所指的单元,于是改变形参指针所指单元的值,也就是改变实参指针所指单元的值。指针类型实参指针类型形参地址值262、指针变量作为函数参数指针作为函数参数:指针类型实参指针举例对两个数按降序排列(2)swap(int*p1,int*p2){intt;t=*p1;*p1=*p2;*p2=t;}#include<stdio.h>voidmain(){inta,b;int*pointer1,*pointer2;scanf(”%d,%d”,&a,&b);pointer1=&a;pointer2=&b;if(a<b)swap(pointer1,pointer2);printf(”%d,%d\n”,a,b);}若改变的是形参指针的值而不是形参指针所指单元的值,还能实现a和b两个变量的交换吗?

35……abp1p2t2000pointer1pointer22000200220022000200253327举例对两个数按降序排列(2)swap(int*p1,举例对两个数按降序排列(3)swap(int*p1,int*p2){int*t;t=p1;p1=p2;p2=t;}#include<stdio.h>voidmain(){inta,b;int*pointer1,*pointer2;scanf(”%d,%d”,&a,&b);

pointer1=&a;pointer2=&b;

if(a<b)swap(pointer1,pointer2);printf(”%d,%d\n”,a,b);}改变形参指针的值无法实现a和b两个变量的交换!

35……abp1p2t2000pointer1pointer22000200220022000200220022000200028举例对两个数按降序排列(3)swap(int*p1,普通变量的指针作函数参数小结欲通过函数调用得到n个要改变的值,主调函数:设置n个普通变量(a1,a2,……)存放n个要改变的值,并用n个指针变量(pa1,pa2,……)指向它们;被调函数:设置n个指针变量(p1,p2,……)作为形参,函数体改变*p1,*p2,……的值;函数调用:主调函数以pa1,pa2,……为实参,将a1,a2,……的地址传给形参p1,p2,……,于是,被调函数改变*p1,*p2,……的值实际上就是改变a1,a2,……的值。因此,函数调用结束,主调函数得到改变了的值。29普通变量的指针作函数参数小结欲通过函数调用得到n个要改变3、数组作为函数参数

数组元素作为函数参数数组名作为函数参数303、数组作为函数参数数组元素作为函数参数30数组元素作为函数参数例7.15:对应元素比较,如果数组a中的元素比数组b中元素大的次数多,则数组a大于数组b,反之数组b大于数组a,如果两数组元素大于对方的元素次数相等,则两数组相等。通过调用large函数实现:large(intx,inty){intflag;if(x>y)flag=1;elseif(x==y)flag=0;elseflag=-1;return(flag);}31数组元素作为函数参数例7.15:对应元素比较,如果数举例判断两个数值型数组的大小#include<stdio.h>voidmain(){inta[10],b[10],i,n=0,k=0;for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<10;i++)scanf("%d",&b[i]);for(i=0;i<10;i++)

if(large(a[i],b[i])==1)n++;

elseif(large(a[i],b[i])==-1)k++;if(n>k)printf("aislargerthanb\n");

elseif(n<k)printf("bislargerthana\n");

elseprintf("aisequaltob\n");}数组元素a[i]、b[i]作实参

32举例判断两个数值型数组的大小#include<stdi一维数组名作为函数参数形参接收实参传递的数组首地址,实际上,C编译是将形参数组名作为指针变量来处理的。参数传递:地址值实参数组指针形参数组名或指针变量效果:函数调用期间,形参数组就是实参数组。一维数组名

一维数组名

一维数组指针一维数组指针变量实参

形参33一维数组名作为函数参数形参接收实参传递的数组首地址,实际上,一维数组名作参数使用说明实参数组与形参数组类型要一致。实参数组和形参数组大小可以不一致,也可以不指定形参数组第一维的大小,因为C编译对形参数组第一维大小不做检查,函数调用时不是把实参数组的值传递给形参数组,而是把实参数组的首地址传递给形参数组,于是形参数组结合到实参数组所占用的存储空间。为方便编程,通常另设一参数用于传递数组元素的个数。

34一维数组名作参数使用说明实参数组与形参数组类型要一致。3例7.17编写函数统计一个一维数组(10个元素)中非0元素的个数。#include<stdio.h>intsolve(intb[10])/*一维数组名b作形参*/{intsum=0,i;for(i=0;i<10;i++)if(b[i]!=0)sum++;return(sum);} voidmain(){inta[10],num,i;for(i=0;i<10;i++)scanf("%d",&a[i]);num=solve(a);/*一维数组名a作实参*/printf("num=%d\n",num);}35例7.17编写函数统计一个一维数组(10个元素)中非0元例7.17编写函数统计一个一维数组(10个元素)中非0元素的个数。#include<stdio.h>intsolve(intb[],intn)/*一维数组名b作形参*/{intsum=0,i;for(i=0;i<n;i++)if(b[i]!=0)sum++;return(sum);} voidmain(){inta[10],num,i;for(i=0;i<10;i++)scanf("%d",&a[i]);num=solve(a,10);/*一维数组名a作实参*/printf("num=%d\n",num);}一维形参数组的大小通常不指定,另设一参数用于传递数组元素的个数。

36例7.17编写函数统计一个一维数组(10个元素)中非0元例:编写函数将数组中n个元素按相反顺序存放(1)voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-i-1;t=x[i];x[i]=x[j];x[j]=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

inv(a,10);

printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}形参和实参均为一维数组

37例:编写函数将数组中n个元素按相反顺序存放(1)void方法(2)形参为指针变量,实参为一维数组voidinv(int*x,intn)

{intt,*i,*j,m=(n-1)/2;for(i=x,j=x+n-1;i<=x+m;i++,j--){t=*i;*i=*j;*j=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

inv(a,10);

printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}38方法(2)形参为指针变量,实参为一维数组voidinv(方法(3)形参,实参均为指针变量

voidinv(int*x,intn)

{intt,*i,*j,m=(n-1)/2;for(i=x,j=x+n-1;i<=x+m;i++,j--){t=*i;*i=*j;*j=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2},*p;printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

p=a;inv(p,10);printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}39方法(3)形参,实参均为指针变量voidinv(int方法(4)形参为一维数组,实参为指针变量voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-i-1;t=x[i];x[i]=x[j];x[j]=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2},*p;printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

p=a;inv(p,10);printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}40方法(4)形参为一维数组,实参为指针变量voidinv(折半(二分)查找折半查找法只能对有序数列进行查找,方法如下:假设n个数按由小到大的顺序存放在数组a中,两个位置指针top、bot分别指向查找范围的顶部、底部。取查找范围的中间位置mid=(top+mid)/2,将待查找的数x与a(mid)进行比较,将按以下三种结果分别处理:(1)x=a(mid):已找到,退出查找;41折半(二分)查找折半查找法只能对有序数列进行查找,方法如下:折半(二分)查找(2)x<a[mid]:x只可能落在top和mid-1范围之内,将查找范围的底部改为bot=mid-1,顶部top不变;(3)x>a[mid]:x只可能落在mid+1和bot范围之内,将查找范围的顶部改为top=mid+1,底部bot不变。确定新的查找范围后,重复以上比较,直到找到或者top>bot,退出循环。top>bot表明尝试过所有可能的范围,但没找到。42折半(二分)查找(2)x<a[mid]:x只可能落在top和折半(二分)查找

x=65的查找过程下标数组元素第一次第二次第三次010←top123235341456←mid565←top←top←mid673←bot785←mid8979102←bot←bot43折半(二分)查找

x=65的查找过程下标数组元素第一次第二次折半(二分)查找(数组从小到大)核心部分算法:top=0;bottom=n-1;result=-1;while((top<=bottom)&&(result==-1)){mid=(top+bottom)/2;/*取中间元素*/

if(a[mid]==x)/*所查找的数据是否是中间元素*/ result=mid;/*找到的位置*/

elseif(a[mid]<x) top=mid+1;elsebottom=mid-1;}44折半(二分)查找(数组从小到大)核心部分算法:44折半查找函数的定义

(数组从大到小)intBinarySearch(inta[],intn,intkey)/*key表示要找的数*/{inttop,bottom,mid;if(key>a[0]||key<a[n-1])return-1;/*返回-1表示没找到*/else{top=0;bottom=n-1;while(top<=bottom){mid=(top+bottom)/2; /*取中间元素*/if(a[mid]==key)/*所查找的数据是否是中间元素*/ returnmid; /*返回找到的位置*/elseif(a[mid]>key) top=mid+1;elsebottom=mid-1;}return-1;}/*返回-1表示没找到*/}45折半查找函数的定义

(数组从大到小)intBinarySe例7.24编写一个字符串复制函数。#include<stdio.h>voidstringcopy(chars[],char*t){inti=0;while(*t!='\0'){s[i]=*t;i++;t++;}s[i]='\0';}voidmain(){charstr1[]="IloveBeijing!";char*str2="IloveChina!";stringcopy(str1,str2);printf("str1=%s\nstr2=%s\n",str1,str2);}46例7.24编写一个字符串复制函数。#include<s例7.25改用两个字符指针变量作stringcopy函数的形参#include<stdio.h>voidstringcopy(char*p,char*q){while((*p++=*q++)!='\0');}voidmain(){charstr1[]="IloveBeijing!";char*str2="IloveChina!";stringcopy(str1,str2);printf("str1=%s\nstr2=%s\n",str1,str2);}47例7.25改用两个字符指针变量作stringcopy函数例7.26编写一个求字符串长度函数#include<stdio.h>#include<string.h>intstringlen(chars[]){inti=0,len=0;while(s[i]!='\0'){len++;i++;}returnlen;}voidmain(){char*str;printf("Pleaseinputastring:");gets(str);printf("\nThestringlenthis%4d\n",stringlenth(str));}48例7.26编写一个求字符串长度函数#include<s多维数组名作函数参数例如:floatmax(intarray[3][10])形参多维数组的第一维大小可以不指定floatmax(intarray[][10])正确但是形参多维数组的第二维及其它高维的大小不能省略floatmax(intarray[3][])错误floatmax(intarray[][])错误49多维数组名作函数参数例如:49举例求二维数组最大值函数的定义与调用例7.23#include<stdio.h>max_value(inta[][4]){inti,j,max;max=a[0][0];for(i=0;i<3;i++)for(j=0;j<4;j++)if(a[i][j]>max)max=a[i][j];return(max);}voidmain(){inta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};printf("max=%d\n",max_value(a));}/*形参二维数组的第一维大小可以不指定*/50举例求二维数组最大值函数的定义与调用例7.23/*形7.4函数的嵌套调用和递归调用从什么地方调用函数,就返回到什么地方...调用函数fun1...调用函数fun2main()函数fun2()函数fun1()函数①②⑤⑥⑦⑧⑨④③517.4函数的嵌套调用和递归调用从什么地方调用函数,就返回函数的嵌套调用举例—求cnmvoidmain(){intm,n,t;longc(int,int);scanf("%d%d",&m,&n);if(n>m){t=m;m=n;n=t;}printf("%ld\n",c(m,n));}longc(intm,intn){longf;longfac(int);f=fac(m)/(fac(n)*fac(m-n));return(f);}longfac(intt){inti;longs=1;for(i=1;i<=t;i++)s*=i;return(s);}在main函数中调用c函数在c函数中三次调用fac函数

返回main函数返回c函数函数C:求cnm

函数fac:求t!

52函数的嵌套调用举例—求cnmvoidmain()在m函数的递归调用inta(intn){intd,c;…d=a(c); …}递归函数两要素:1.递归调用2.使递归结束的条件函数的递归调用:在定义一个函数的过程中又直接或间接地调用函数本身

53函数的递归调用inta(intn)函数的递归调用:函数的递归调用f函数调用f函数f2函数调用f1函数f1函数调用f2函数直接递归调用间接递归调用54函数的递归调用f函数调用f函数f2函数调用递归函数举例1—求阶乘例7.31分析:1(n=0,1)fac(n)=n*fac(n-1)(n>1)floatfac(intn)/*求阶乘函数*/{floatf;if(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}#include<stdio.h>voidmain(){intn;scanf("%d",&n);if(n<0)printf("n<0,dataerror!");elseprintf("%d!=%15.0f\n",n,fac(n));}递归调用递归结束条件55递归函数举例1—求阶乘例7.31分析:1递归函数举例1—年龄问题例7.32分析:age(n-1)+2(n>1)age(n)=10(n=1)#include<stdio.h>age(intn){intc;if(n==1)c=10;elsec=age(n-1)+2;return(c);}voidmain(){printf("%d\n",age(5));}递归调用递归结束条件递归调用递归调用递归结束条件递归调用递归结束条件递归结束条件递归调用递归结束条件56递归函数举例1—年龄问题例7.32分析:递归函数举例3#include<stdio.h>voidtry(){charc;if((c=getchar())!=’#’){try();putchar(c);}}voidmain(){try();}输入apple#后的结果是:

------------elppa57递归函数举例3#include<stdio.h>输入7.5函数的返回值为指针一个函数可以返回整型、字符型、实型函数值,也可以返回一个指针值,即将地址作为函数值返回到主调函数中。返回指针的函数的定义:类型名*函数名(参数表){函数体语句组}587.5函数的返回值为指针一个函数可以返回整型、字符型、实型例7.34编写一函数,实现两个字符串的连接,返回值为连接后字符串的首地址。#include<stdio.h>char*strcat(char*s1,char*s2)/*定义返回值是指针的函数*/{char*p=s1;while(*p!='\0')p++;while((*p++=*s2++)!='\0');*p='\0';returns1;}voidmain(){charstr1[30]="Ilearn",*str2="Clanguage.";char*s;s=strcat(str1,str2);/*strcat函数的返回值是指针*/printf("%s\n",s);}59例7.34编写一函数,实现两个字符串的连接,返回值为连接例7.29编写程序,使能从输入的若干个字符串中找出最小的串,并将其输出。#include<stdio.h>#include<string.h>intgetstring(charc[][81]){charlin[81],linnum=0;printf("Enterstringaspacestringtoend!\n");gets(lin);while(!strcmp(lin,"#")==0){strcpy(c[linnum],lin);linnum++;gets(lin);}returnlinnum;}/*返回字符串行数*/60例7.29编写程序,使能从输入的若干个字符串中找出最小的接上页char*findminstr(char(*s)[81],intnum)/*s是指向一维数组的指针*/{char*strq;inti;strq=s[0];for(i=1;i<num;i++)if(strcmp(s[i],strq)<0)/*寻找最小串*/ strq=s[i];returnstrq;}/*返回最小串的地址*/61接上页char*findminstr(char(*s)[接上页voidmain(){charstr[50][81],*strp;intn,i;n=getstring(str);strp=findminstr(str,n);puts(strp);}62接上页voidmain()62例7.29编写程序,使能从输入的若干个字符串中找出最小的串,并将其输出。#include<stdio.h>#include<string.h>intgetstring(charc[][81]){charlin[81],linnum=0;printf("Enterstringaspacestringtoend!\n");gets(lin);while(!strcmp(lin,“#”)==0)/*输入遇#号结束*/{strcpy(c[linnum],lin);linnum++;gets(lin);}returnlinnum;}/*返回字符串行数*/63例7.29编写程序,使能从输入的若干个字符串中找出最小的接上页char*findminstr(char(*s)[81],intnum)/*s是指向一维数组的指针*/{char*strq;inti;strq=s[0];for(i=1;i<num;i++)if(strcmp(s[i],strq)<0)/*寻找最小串*/ strq=s[i];returnstrq;}/*返回最小串的地址*/S[][81]64接上页char*findminstr(char(*s)[接上页voidmain(){charstr[50][81],*strp;intn,i;n=getstring(str);strp=findminstr(str,n);puts(strp);}65接上页voidmain()657.6变量的作用域和存储类别函数间数据传递的渠道:主调函数(普通变量参数)被调函数主调函数(函数返回值)被调函数主调函数(数组参数/指针变量参数)被调函数主调函数(全局变量)被调函数667.6变量的作用域和存储类别函数间数据传递的渠道:6局部变量#include<stdio.h>voidsub(int,int);voidmain(){inta=1,b=2;sub(a,b);printf("mainprogram%d%d\n",a,b);}voidsub(inta,intb){a=a+10;b=b+20;printf("subprogram%d%d\n",a,b);}程序结果:subprogram1122mainprogram1267局部变量#include<stdio.h>程序结果:67局部变量和全局变量变量按照其作用范围分为局部变量和全局变量(外部变量)。

类别作用域

(有效范围)局

量函数形参本函数在函数体首部定义的变量/数组本函数在复合语句首部定义的变量/数组本复合语句全局

变量在函数之外定义的变量/数组定义起至文件结束68局部变量和全局变量变量按照其作用范围分为局部变量和全局变量(局部变量和全局变量两点说明:①不同函数中的局部变量可以同名,全局变量与局部变量也可以同名,但它们代表不同的变量,在内存中占有不同的存储空间。②局部变量起作用时,同名全局变量不起作用。69局部变量和全局变量两点说明:69局部变量和全局变量例7.41#include<stdio.h>inta=3,b=5;max(inta,intb){intc;c=a>b?a:b;return(c);}voidmain()

{inta=8;

printf("%d\n",max(a,b));}max()的局部变量a、bmax()的局部变量c实参a是main()的局部变量(8),实参b是全局变量(5)程序运行结果:8

使用max()的局部变量a、b

main()的局部变量a

全局变量a、b

70局部变量和全局变量例7.41#include<stdio全局变量intP1=1,P2=2;floatf1(inta){……}charc1,c2;floatf2(intb){……}voidmain(){……}全局变量P1,P2作用范围全局变量c1,c2作用范围一个不成文的约定:全局变量名的第一个字母大写。71全局变量intP1=1,P2=2;全局变量P1,P2作全局变量应用举例例7.40有一个一维数组,内放10个学生的成绩,写一个函数,求出平均分、最高分和最低分。#include<stdio.h>floatMax,Min;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];elseif(array[i]<Min)Min=array[i];

sum=sum+array[i];}aver=sum/n;return(aver);}全局变量能在定义之后的所有函数中使用72全局变量应用举例例7.40有一个一维数组,内放10个学生全局变量应用举例voidmain(){floatave;floatscore[10],i;for(i=0;i<10;i++)scanf("%f",&score[i]);ave=average(score,10);printf("max=%6.2f\n",Max);printf("min=%6.2f\n",Min);printf("average=%6.2f\n",ave);}73全局变量应用举例voidmain()73变量的存储类型局部变量按其生存的时间(生存期)划分为动态存储变量、静态存储变量和寄存器变量。变量定义完整格式:[存储类别]数据类型变量表列;存储类别缺省为auto(自动型)74变量的存储类型局部变量按其生存的时间(生存期)划分为动态存内存中用户区存储空间的分配内存

系统区用户区(存放用户数据与程序)存放系统程序程序区:程序静态存储区:全局变量静态局部变量动态存储区:自动局部变量形式参数函数调用时现场保护和返回值75内存中用户区存储空间的分配内存变量的存储类型动态变量静态变量类别

存储类别为auto(通常缺省)的局部变量存储类别为static的

局部变量存储类别为register的局部变量所有类别的全局变量存储

位置动态存储区静态存储区寄存器生存期函数运行期间程序运行期间赋初值每调用函数一次,赋初值一次只在编译时赋初值一次(数值型默认初值为0)(字符型默认初值为空字符)76变量的存储类型动态变量静态变量类别

存储类别为auto局部静态变量应用举例1#include<stdio.h>f(inta){autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b

温馨提示

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

评论

0/150

提交评论