资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第七章 函 数,函数的定义、说明和调用的方法,变量的存储类及其作用域,函数间的数据传递,函数,模块化编程,学生成绩档案管理软件,成绩输入 成绩修改 成绩排序 成绩打印,模块化编程(又称为结构化编程):,把一个复杂的问题分解成易于理解和易于实现的小问题。,例:编写学生成绩档案管理软件,模块化编程,总结:,在,C,语言中,函数是实现模块化编程的基本模块,即模块化编程是通过函数实现的。,c,语言源程序,文件,n,文件,2,文件,1,函数,1,函数,m,函数,2,C,语言的程序结构,C,语言的程序结构,总结:,C,语言程序是由函数构成的,每个函数是由,C,语句组成的。,一个,C,程序中,有且只有一个以,main,命名的主函数。,思考:,假设在,1,个,C,程序中,文件,1,中已有,main,函数,请问文件,2,中有没有,main,函数?,含有,main,函数的文件成为主文件,请问,1,个程序中有几个主文件?,C,语言的程序结构,每个函数在程序中的位置都是任意的。函数与函数之间是独立的、平等的,不能在一个函数中定义另一个函数。,判断题:,主函数可以在程序的开始位置,也可以在程序的末尾。,(),函数的定义允许出现嵌套。,(),C,语言的程序结构,函数由函数的首部和函数体构成,在函数体内由说明语句和执行语句构成,说明语句在前,执行语句在后。,判断题:,main(),int a;,scanf(%d,float b=1;,printf(%d,%f,a,b);,函数的分类:,标准函数(库函数),自定义函数,函数,#include,scanf printf getchar putchar gets puts,#include,strcpy strncpy strcat strcmp strlen,#include,fabs(,求绝对值,)sqrt(,开平方根,),例:求 的值,#include,main(),float k=4,s;,s=sqrt(k);,printf(%f,s);,自定义函数,引例,main(),int k,n,m;,long fk,fn,fm;,scanf(%d%d%d,printf(%f,fk*1.0/(fn+fm);,fk=1;,for(i=1;i=k;i+),fk=fk*i;,fn=1;,for(i=1;i=n;i+),fn=fn*i;,fm=1;,for(i=1;i=m;i+),fm=fm*i;,x!,f=1;,for(i=1;i=x;i+),f=f*i;,需要定义一个能实现阶乘的函数,这样就可以直接调用了。,函数的定义,函数定义的格式:,存储类说明符,函数类型标识符,函数名,(,参数类型 参数名,),说明语句,执行语句,存储类说明符:,函数的类型标识符:,指定函数返回值的类型,省略时是,int,型,函数名:,函数定义的说明,参数:,个数:,注意:,如果有多个类型相同的参数,必须将类型分别给出,作用:,在被调用的时候,接收送来的数据,。,小括号:,函数体:,函数定义的说明,main(),max(int x,int y),主调函数:,main(),int a,b,s;,scanf(%d%d,s=qiuhe(a,b);,printf(%d,s);,例:,编程实现两个整数的求和,其中求和写成一个函数。,被调函数:,自定义函数,qiuhe,的定义,int qiuhe(int x,int,y),int z;,z=x+y;,return,(,z,),;,例:编程计算下面表达式的值,其中一个函数求一个数的阶乘。,函数的说明,函数说明,的形式:,存储类说明符 函数类型说明符函数名,(,参数类型及参数说明表,);,存储类说明符 函数类型说明符函数名,(,参数类型说明表,);,例:,说明写在哪里,如何写(用第一种形式)?,例:,说明写在哪里,如何写(用第二种形式)?,在以下情形下可以不写函数说明语句,:,被调用函数定义在先,主调函数定义在后,被调用函数是,int,型的,在程序的所有函数定义之前,有被调函数的外部声明,函数的说明,但建议大家不要省略函数的说明,说明:,参数叫实参,可以是常量、变量和表达式。,实参,必须与,形参,之间,个数,相等,,类型,一致。,实参,可以与,形参,同名,但是它们是名字相同的,不同变量,。,函数的调用,函数调用的格式:,函数名(参数表),函数名(参数表)与表达式的使用方法一样。,例:,计算,s=1!+2!+,+n!,#include,long jiecheng(int x),int i;,long s=1;,for(i=1;i=x;i+),s=s*i;,return s;,main(),int i,n;,long s=0;,scanf(%d,for(i=1;i0;i-),fun();,fun(),int j=2;,printf(,“,j=%d,k=%dn,”,j,k);,k,=,k,*,k,;,j=j*j;,int k;,生存期,作用域,自动存储类,作用域和生存期:,定义开始,到所在,函数结束,外部存储类,作用域:,可以使整个程序,生存期:,整个程序,变量定义的格式:,static,数据类型 变量名表,;,定义的位置:,生存期:,整个程序,特点:,初始化仅执行一次,作用域:,静态存储类,内部静态变量,外部静态变量,函数内部,函数外部,函数内部 从定义开始到函数或复合语句结束为止,函数外部 从定义开始到文件结束为止,int g=1;,void fun();,void main(),int i;,for(i=0;i3;i+),fun();,void fun(),int l=1;,static int s_l=1;,printf(,“,g=%d,l=%d,s_l,=%dn,”,g,l,s_l);,g+;,l+;,s_l+;,作用域,生存期,外部存储类,生存期:,整个程序,作用域:,可以使整个程序,静态存储类,生存期:,整个程序,作用域:,定义开始,到所在,函数结束,将,static int s_l=1;,改为,static int s_l;,s_l=1;,运行结果如何?,寄存器变量定义的格式:,register,数据类型 变量名表,;,特点:,比自动变量存取速度快,存放在寄存器中,但寄存器的数目有限,如不够则自动放在内存中,没有地址,,register int x;scanf(,“,%d,”,寄存器存储类,用,数据,的复制方式传送数据,用,地址,的复制方式传送数据,利用外部变量传送数据,函数间的数据传送,传值调用特征:,实参,是,表达式(包括常量、变量),,,形参,是,变量,。,实参的值传送给形参变量,被调用函数无法直接改变主调函数里数据的值。,注:,形参的空间是在被调用后才为其分配的,实参名可以与形参名相同,但是他们是不同的变量,用数据的复制方式传送数据,传值调用,主调函数,#include,main(),int x=1,y=2;,f(,x,y,);,printf(%d,%dn,x,y);,被调函数,f(int x,int y),int t;,t=x;,x=y;,y=t;,printf(%d,%dn,x,y);,实参,形参,用来接受实,参传来的信息,int x=,x,y=,y,;,被调函数不能改变主调,函数里数据的值,传值调用特征:,实参,是地址,,形参,是指针变量。,变量的地址赋给形参指针变量后,处理形参指针变量所指的,值实际是处理实参。,因此,被调函数的操作可以改变主调函数里数据的值。,用地址的复制方式传送数据,传址调用,对于普通变量:变量的地址,P,197,对于数值类型的数组:数组名,P,202,对于字符型的数组:数组名,P,203,同类型的指针变量,同类型的数组或者指针变量,字符型的数组或者指针变量,#include,main(),int a=10,b=20;,printf(,“,a=%d,b=%dn,a,b);,fun1(,printf(a=%d,b=%dn,a,b);,普通变量和函数,fun1(int*x,int*y),int temp;,temp=*x;,*x=*y;,*y=temp;,printf(*x=%d,*y=,%dn,*x,*y);,实参:普通变量地址,形参:指针变量,int*x=,&a,*y=,&b,;,被调函数改变了主调,函数里数据的值,#include,main(),int a=10,b=20;,printf(,“,a=%d,b=%dn,a,b);,fun1(,printf(a=%d,b=%dn,a,b);,普通变量和函数,fun1(int*x,int*y),int*temp;,temp=x;,x=y;,y=temp;,printf(*x=%d,*y=,%dn,*x,*y);,被调函数并不一定改变主调,函数里数据的值,main(),int a3=1,2,3;,f(a);,printf(%d,a2);,f(int b),b2=9;,main(),int a3=1,2,3;,f(a);,printf(%d,a2);,f(int*p),*(p+2)=9;,数组和函数,实参:数组名,形参:数组,为,a,数组起了一个别名,实参:数组名,形参:指针变量,int*p=a;,main(),char a30=hello;,f(a);,puts(a);,f(char b),strcpy(b,hello Mary);,main(),char a30=hello;,f(a);,puts(a);,f(char*p),strcpy(p,hello Mary);,字符串和函数,实参:数组名,形参:指针变量,int*p=a;,int sum;,main(),int n;,sum=0;,scanf(“%d”,s(n);,printf(“%d”,sum);,int s(int m),int i;,for(i=0;i=m;i+),sum=sum+i;,总结被调函数给主调函数传递数据的方式:,对于数值传递:利用,return,语句返回数据,但是被调函数只能给主调函数返回一个数据。,对于地址传递:利用在被调函数里直接改变,*形参,,可以在被调函数里一次改变多个主调函数的数据。,也可以利用外部变量,实现数据的传递,但是不建议使用,因为外部变量打破了函数的独立性。,
展开阅读全文