《C语言函数.ppt》由会员分享,可在线阅读,更多相关《C语言函数.ppt(42页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第七章第七章 函函 数数 函数的定义、说明和调用的方法 变量的存储类及其作用域 函数间的数据传递函数函数 模块化编程模块化编程 学生成绩档案管理软件成绩输入 成绩修改 成绩排序 成绩打印模块化编程(又称为结构化编程):把一个复杂的问题分解成易于理解和易于实现的小问题。例:编写学生成绩档案管理软件模块化编程模块化编程 总结:在C语言中,函数是实现模块化编程的基本模块,即模块化编程是通过函数实现的。c c语言源程序语言源程序文件文件n n文件文件2 2文件文件1 1函数函数1 1函数函数m m函数函数2 2C语言的程序结构语言的程序结构 C语言的程序结构语言的程序结构 总结:1.C语言程序是由函数
2、构成的,每个函数是由C语句组成的。2.一个C程序中,有且只有一个以main命名的主函数。思考:1.假设在1个C程序中,文件1中已有main函数,请问文件2中有没有main函数?2.含有main函数的文件成为主文件,请问1个程序中有几个主文件?C语言的程序结构语言的程序结构 3.每个函数在程序中的位置都是任意的。函数与函数之间是独立的、平等的,不能在一个函数中定义另一个函数。判断题:1.主函数可以在程序的开始位置,也可以在程序的末尾。()2.函数的定义允许出现嵌套。()C语言的程序结构语言的程序结构 4.函数由函数的首部和函数体构成,在函数体内由说明语句和执行语句构成,说明语句在前,执行语句在后
3、。判断题:main()int a;scanf(%d,&a);float b=1;printf(%d,%f,a,b);函数的分类:标准函数(库函数)自定义函数函数函数#include scanf printf getchar putchar gets puts#include strcpy strncpy strcat strcmp strlen#include fabs(求绝对值求绝对值)sqrt(开平方根开平方根)例:求例:求 的值的值#includemain()float k=4,s;s=sqrt(k);printf(%f,s);自定义函数自定义函数引例引例main()int k,n,m;
4、long fk,fn,fm;scanf(%d%d%d,&k,&n,&m);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;需要定义一个能实现阶乘的函数,这样就可以直接调用了。函数的定义函数的定义 函数定义的格式:函数定义的格式:存储类说明符存储类说明符 函数类型标识符函数类型标识符 函数名函数名(参数类型参数类型 参数名参数名)说明语句说明语句 执行语句执行语句 1.存储类
5、说明符:2.函数的类型标识符:指定函数返回值的类型,省略时是int型3.函数名:函数定义的说明函数定义的说明 4.参数:个数:注意:如果有多个类型相同的参数,必须将类型分别给出作用:在被调用的时候,接收送来的数据。5.小括号:6.函数体:函数定义的说明函数定义的说明 main()max(int x,int y)主调函数:主调函数:main()int a,b,s;scanf(%d%d,&a,&b);s=qiuhe(a,b);printf(%d,s);例:例:编程实现两个整数的求和,其中求和写成一个函数。编程实现两个整数的求和,其中求和写成一个函数。被调函数:被调函数:自定义函数qiuhe的定义i
6、nt qiuhe(int x,int y)int z;z=x+y;return(z);例:编程计算下面表达式的值,其中一个函数求一个数例:编程计算下面表达式的值,其中一个函数求一个数的阶乘。的阶乘。函数的说明函数的说明 函数说明函数说明的形式:的形式:存储类说明符存储类说明符 函数类型说明符函数名函数类型说明符函数名(参数类型及参数说明表参数类型及参数说明表););存储类说明符存储类说明符 函数类型说明符函数名函数类型说明符函数名(参数类型说明表参数类型说明表););例:例:说明写在哪里,如何写(用第一种形式)?说明写在哪里,如何写(用第一种形式)?例:例:说明写在哪里,如何写(用第二种形式)
7、?说明写在哪里,如何写(用第二种形式)?在以下情形下可以不写函数说明语句在以下情形下可以不写函数说明语句:1.1.被调用函数定义在先,主调函数定义在后被调用函数定义在先,主调函数定义在后2.2.被调用函数是被调用函数是intint型的型的3.3.在程序的所有函数定义之前,有被调函数的外部声明在程序的所有函数定义之前,有被调函数的外部声明函数的说明函数的说明 但建议大家不要省略函数的说明但建议大家不要省略函数的说明说明:说明:1.1.参数叫实参,可以是常量、变量和表达式。参数叫实参,可以是常量、变量和表达式。2.2.实参实参必须与必须与形参形参之间之间个数个数相等,相等,类型类型一致。一致。实参
8、实参可以与可以与形参形参同名,但是它们是名字相同的同名,但是它们是名字相同的不同变量不同变量。函数的调用函数的调用 函数调用的格式:函数调用的格式:函数名(参数表)函数名(参数表)函数名(参数表)与表达式的使用方法一样。函数名(参数表)与表达式的使用方法一样。例:例:计算s=1!+2!+n!#includelong 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,&n);for(i=1;i0;i-)fun();fun()int j=2;printf(“j=%d
9、,k=%dn”,j,k);k=k*k;j=j*j;int k;生存期作用域自动存储类作用域和生存期:定义开始,到所在函数结束外部存储类作用域:可以使整个程序生存期:整个程序变量定义的格式:变量定义的格式:static 数据类型 变量名表;定义的位置:定义的位置:生存期:生存期:整个程序特点:特点:初始化仅执行一次初始化仅执行一次作用域:作用域:静态存储类静态存储类 内部静态变量内部静态变量外部静态变量外部静态变量函数内部函数内部函数外部函数外部函数内部 从定义开始到函数或复合语句结束为止函数外部 从定义开始到文件结束为止int g=1;void fun();void main()int i;f
10、or(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 数据类型 变量名表;特点:特点:1.比自动变量存取速度快2.存放在寄存器中,但寄存器的数目有限,如不够则自动放
11、在内存中3.没有地址,register int x;scanf(“%d”,&x);寄存器存储类寄存器存储类 用数据的复制方式传送数据用地址的复制方式传送数据利用外部变量传送数据函数间的数据传送函数间的数据传送 传值调用特征:传值调用特征:1.1.实参实参是是表达式(包括常量、变量)表达式(包括常量、变量),形参形参是是变量变量。2.2.实参的值传送给形参变量,被调用函数无法直接改变主调实参的值传送给形参变量,被调用函数无法直接改变主调函数里数据的值。函数里数据的值。注:注:形参的空间是在被调用后才为其分配的形参的空间是在被调用后才为其分配的 实参名可以与形参名相同,但是他们是不同的变量实参名可
12、以与形参名相同,但是他们是不同的变量用数据的复制方式传送数据用数据的复制方式传送数据传值调用传值调用主调函数#includemain()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;被调函数不能改变主调函数里数据的值传值调用特征:传值调用特征:实参实参是地址,是地址,形参形参是指针变量。是指针变量。变量的地址赋给形参指针变量后,处理形参指针变量所指的变量的地址赋给形参指针变量后,处理形参指针变量所指的
13、值实际是处理实参。值实际是处理实参。因此,被调函数的操作可以改变主调函数里数据的值。因此,被调函数的操作可以改变主调函数里数据的值。用地址的复制方式传送数据用地址的复制方式传送数据传址调用传址调用 对于普通变量:变量的地址P197对于数值类型的数组:数组名 P202对于字符型的数组:数组名 P203同类型的指针变量同类型的数组或者指针变量字符型的数组或者指针变量#include main()int a=10,b=20;printf(“a=%d,b=%dn,a,b);fun1(&a,&b);printf(a=%d,b=%dn,a,b);普通变量和函数普通变量和函数 fun1(int*x,int*
14、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(&a,&b);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);被调函数并不一定改变主调函数里数据的值
15、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”,&n);s(n);printf(“%d”,sum);int s(int m)int i;for(i=0;i=m;i+)sum=sum+i;总结被调函数给主调函数传递数据的方式:1.对于数值传递:利用return语句返回数据,但是被调函数只能给主调函数返回一个数据。2.对于地址传递:利用在被调函数里直接改变*形参,可以在被调函数里一次改变多个主调函数的数据。3.也可以利用外部变量,实现数据的传递,但是不建议使用,因为外部变量打破了函数的独立性。
限制150内