1 / 29

第六章 函数

第六章 函数. 主要内容. C 程序的模块化结构 函数的定义 函数的参数与返回值 函数的调用 函数的嵌套调用 数组作为函数参数. 函数概念. 基本思想:将一个大的程序按功能分割成一些小模块, 函数对应于程序的模块,一般 先定义后使用 。. ATM 自动查询系统. 读取银行卡信息. 取款. 查询帐户. 转帐. 修改密码. 人民币帐户. 人民币帐户. 卡内转帐. 港元帐户. 其它帐户. 港元帐户. 其它帐户. 美元帐户. 美元帐户. 基本思想:将一个大的程序按功能分割成一些小模块, 函数对应于程序的模块,一般 先定义后使用 。.

spence
Download Presentation

第六章 函数

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第六章 函数

  2. 主要内容 • C程序的模块化结构 • 函数的定义 • 函数的参数与返回值 • 函数的调用 • 函数的嵌套调用 • 数组作为函数参数

  3. 函数概念 • 基本思想:将一个大的程序按功能分割成一些小模块,函数对应于程序的模块,一般先定义后使用。 ATM自动查询系统 读取银行卡信息 取款 查询帐户 转帐 修改密码 人民币帐户 人民币帐户 卡内转帐 港元帐户 其它帐户 港元帐户 其它帐户 美元帐户 美元帐户

  4. 基本思想:将一个大的程序按功能分割成一些小模块,函数对应于程序的模块,一般先定义后使用。基本思想:将一个大的程序按功能分割成一些小模块,函数对应于程序的模块,一般先定义后使用。

  5. C是模块化程序设计语言 C程序结构 • C是函数式语言 • 必须有且只能有一个名为main的主函数 • C程序的执行总是从main函数开始,在main中结束 • 函数不能嵌套定义,可以嵌套调用

  6. fun11() { … retrun; } fun1() { … fun11(); … retrun; } Void main() { … fun1(); … fun2(); … } fun21() { … retrun; } fun2() { … fun21(); … fun22(); … retrun; } fun22() { … retrun; }

  7. 例: 打印图形: ****************** How do you do! ****************** ****************** void printstar() { printf(“**************\n” ); } main() { printstar(); printf(“ How do you do!\n”): printstar(): printstar(): } 编程: main() { printf(“****************\n”); printf(“How do you do! \n”); printf(“******************\n”); printf(“******************\n”); } 三个语句一样,可编写成函数:

  8. 函数分类 • 从用户角度 • 标准函数(库函数):由系统提供,如printf(),scanf(),putchar,getchar • 用户自定义函数 • 从函数形式 • 无参函数 • 有参函数 使用库函数应注意: 1、函数功能 2、函数参数的数目和顺序,及各参数意义和类型 3、函数返回值意义和类型 4、需要使用的包含文件: #include <*.h>

  9. 例 有参函数(现代风格) float max(float x, y) {float m; if (x>y) m=x; else m=y; return(m); } 例 空函数 dummy( ) { } 函数体为空 6-1 函数的定义 合法标识符 • 一般格式 现代风格: 函数属性 函数类型 函数名(形参类型说明表) { 说明部分 语句部分 } 像普通变量一样定义,在函数中也像普通变量一样使用 内部函数:static 外部函数:extern 函数体 例 有参函数(现代风格) float max(float x, float y) {float m; if (x>y) m=x; else m=y; return(m); } 例 无参函数 printstar( ) { printf(“**********\n”); } 或 printstar(void ) { printf(“**********\n”); }

  10. 函数传统风格和例子 函数类型 函数名(形参表) 形参类型说明 { 说明部分 语句部分 } 传统风格: 例 有参函数(传统风格) float max(x,y) float x,y; { float z; z=x>y?x:y; return(z); }

  11. 6-3 函数的调用 • 调用形式 函数名(实参表);或者函数名(); 说明: 1、调用的是有参函数,则要求 • 实参与形参个数相等,类型一致,按顺序一一对应 • 实参表求值顺序,因系统而定(Turbo C 自右向左) • 实参可以是表达式。如果是表达式实参,先计算表达式的值再将数据传递给形参。 2、如果调用的是无参函数,则无实参表,此时小括号不能省略。

  12. 6-2 函数的返回值 例 无返回值函数 void swap(int x,int y ) { int temp; temp=x; x=y; y=temp; } 例 有参函数(现代风格) float max(float x, float y) {float m; if (x>y) m=x; else m=y; return(m); } • 返回语句 • 形式: return(表达式); 或return 表达式; 或return; • 功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数 • 说明: • 函数中可有多个return语句 • 若无return语句,遇}时,自动返回调用函数 • 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换------函数调用转换 • void型函数,可以不用return

  13. b x a y a b 10 10 20 10 20 20 t t 10 例子:6—4 #include <stdio.h> int swap(int a,int b); main() { int x=10,y=20; printf("(1)x=%d y=%d\n",x,y); swap(x,y); printf("(4)x=%d y=%d\n",x,y); } int swap(int a,int b) { int t; printf("(2)a=%d b=%d\n",a,b); t=a;a=b;b=t; printf("(3)a=%d b=%d\n",a,b); }

  14. t 7.0 7.0 2.0 2.0 3.0 3.0 x a y b c z m 函数调用 被调用函数 #include <stdio.h> float max(x,y,z) float x,y,z; { float t; t=x; if(y>t) t=y; if(z>t) t=z; return t; } main() { float m,a=3.0,b=7.0,c=2.0; m=max(a,b,c); printf("%f",m); } a b c max(a,b,c) <>m x y z t 主调用函数, 值与return后的参数一样

  15. 函数调用方式 • 表达式方式,调用后返回一个值参加运算:y=max(a,b)+max(c,d) • 语句方式: max(a,b); • 函数调用作为另外一个函数的参数。 • 如:m=max(max(a,b),max(c,d)) #include <stdio.h> float max(float x,float y) { float t; t=x; if (y>t) t=y; return t; } main() { float y,a=3.0,b=7.0,c=2.0; y=max(a,b)+max(c,d); printf("%f",y); }

  16. 被调函数的说明 • 被调函数返回类型 被调函数名(形参表); • 一般函数要在主调函数前说明,如果在主调函数前定义则不用说明。 #include <stdio.h> float max(float x,float y) { float t; t=x; if (y>t) t=y; return t; } main() { float y,a=3.0,b=7.0,c=2.0; y=max(a,b)+max(c,d); printf("%f",y); } #include <stdio.h> float max(float x,float y); main() { float y,a=3.0,b=7.0,c=2.0; y=max(a,b)+max(c,d); printf("%f",y); } float max(float x,float y) { float t; t=x; if (y>t) t=y; return t; }

  17. 函数的参数 • 参数传递分为传值与传地址两种方式。 • 传值方式将对应表达式的值传给相应的实参,实参与形参占有不同的存储单元,形参的改变不会影响实参。 • 传地址方式将实参的地址传递给形参,实参与形参共享存储单元,这时形参的改变引起实参的改变。一般用指针与数组完成,用以带回多个值。

  18. t 7.0 7.0 2.0 2.0 3.0 3.0 x a y b c z m 函数调用 被调用函数 • 例子:6—3 #include <stdio.h> float max(x,y,z) float x,y,z; { float t; t=x; if(y>t) t=y; if(z>t) t=z; return t; } main() { float m,a=3.0,b=7.0,c=2.0; m=max(a,b,c); printf("%f",m); } a b c max(a,b,c) <>m x y z t 主调用函数, 值与return后的参数一样

  19. b x a y a b 10 10 20 10 20 20 t t 10 例子:6—4 #include <stdio.h> int swap(int a,int b); main() { int x=10,y=20; printf("(1)x=%d y=%d\n",x,y); swap(x,y); printf("(4)x=%d y=%d\n",x,y); } int swap(int a,int b) { int t; printf("(2)a=%d b=%d\n",a,b); t=a;a=b;b=t; printf("(3)a=%d b=%d\n",a,b); }

  20. x y x y 10 20 20 10 a b t t 10 例子:6—4 #include <stdio.h> int swap(int* a,int* b); main() { int x=10,y=20; printf("(1)x=%d y=%d\n",x,y); swap(&x,&y); printf("(4)x=%d y=%d\n",x,y); } int swap(int* a,int* b) { int t; printf("(2)a=%d b=%d\n",*a,*b); t=*a;*a=*b;*b=t; printf("(3)a=%d b=%d\n",*a,*b); }

  21. 6-6 只能被1和它本身整除的数为素数。 int pf(n) { int i; int flag; flag=1; for(i=2;i<=n/2;i++) if(n%i==0) {flag=0;break;} return (flag); } main() { int i; int count=0; for(i=2;i<=100;i++) if(pf(i)==1) { printf("%6d",i); count++; if(count%5==0) printf("\n"); } }

  22. 函数的嵌套调用 函数的嵌套调用是指,在执行被调用函数时,被调用函数又调用了其它函数,其关系可表示如图所示。C规定:函数定义不可嵌套,但可以嵌套调用函数。

  23. f( ) f1( ) f2( ) int f2(int t) { int a,c; …… c=f1(a); ……. return(3+c); } int f1(int x) { int y,z; …… z=f2(y); ……. return(2*z); } 调f 调f2 调f1 函数的递归调用 • 定义:函数直接或间接的调用自身叫函数的递归调用。 int f(int x) { int y,z; …… z=f(y); ……. return(2*z); } • 说明 • C编译系统对递归函数的自调用次数没有限制 • 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出

  24. 分析:例子6——9 • 第5个人年龄 • 第4个人年龄+2 转化为:age(n)=age(n-1)+2 18 • 第3个人年龄+2 16 • 第2个人年龄+2 14 • 第1个人年龄+2 12 • 第1个人年龄:10 终止:age(1)=10

  25. age(5)=18 age(5)=age(4)+2 age(4)=16 age(4)=age(3)+2 age(3)=14 age(3)=age(2)+2 age(2)=12 age(2)=age(1)+2 age(1)=10

  26. 例子6——9 age(n) int n; { int a; if(n==1) a=10; else a=age(n-1)+2; return a; } main() {printf("the five pepole's age=%d\n",age(5));}

  27. 函数与数组 • 数组元素作函数实参——值传递 • 数组名作函数参数——地址传递 在主调函数与被调函数分别定义数组,且类型应一致 形参数组大小(多维数组第一维)可不指定 形参数组名是地址变量

  28. 0 1 2 3 4 5 6 7 8 9 s 49 a 9 例子6—13 arrin (int* a) arrin (int a[ ]) arrin (int a[M]) #define M 10 void arrout(int*,int); int arrin(int*); main() {int s[M],k=0; k=arrin(s); arrout(s,k);} arrin(int* a) {int i,x=0; i=0; scanf("%d",&x); while(x>=0) {*(a+i)=x;i++;scanf("%d",&x);} return i;} void arrout(int* a,int n) { int i; for(i=0;i<n;i++) printf(((i+1)%5==0)?"%4d\n":"%4d",*(a+i)); printf("\n"); } i=0

More Related