计算机二级第四章函数.ppt_第1页
计算机二级第四章函数.ppt_第2页
计算机二级第四章函数.ppt_第3页
计算机二级第四章函数.ppt_第4页
计算机二级第四章函数.ppt_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

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

文档简介

第四章 函 数 4.1 概述 4.函数定义的一般形式 4.函数参数和函数的值 4. 函数的调用 4. 函数的嵌套调用 4.函数的递归调用 4.数组作为函数参数 4.8 局部变量和全局变量 4.变量的存储类别 4.10 内部函数和外部函数 一个较大的程序可分为若 干个程序模块,每一个模 块用来实现一个特定的功 能。在高级语言中用子程 序实现模块的功能。子程 序由函数来完成。一个 程序可由一个主函数和若 干个其他函数构成。 由主函数调用其他函数,其他函数也可以互相调用。 同一个函数可以被一个或多个函数调用任意多次。 函数间的调用关系 4.1 概述 # include void main() void printstar(); /*对printstar函数声明*/ void print_message(); /*对print_message函数声明*/ printstar(); *调用printstar函数* print_message(); /*调用print_message函数*/ printstar(); *调用printstar函数*/ 先举一个函数调用的简单例子先举一个函数调用的简单例子1 1: void printstar() *定义printstar函数* printf(“*n“); void print_message() *定义print_message函数* printf(“How do you do!n“); 结果: * How do you do! * 如果下面的函数写在main 之前,函数声明可以省略 #include void main( ) int max(int ,int );/* 对对max函数的声明 */ int ,; scanf(,); max(,); printf(“max is ,); int max(int ,int ) int ; ?; return(); 另一个函数调用的简单例子另一个函数调用的简单例子2 2: 返回值 形参表 说明:说明: 3 、组成C程序的各个函数彼此平行,独立定义,可以 嵌套调用。但不能调用主函数main( ) 1、 一个C程序可以由若干个函数组成。 2、 在组成C程序的所有函数中,有且只有一个主函数 main( ),位置任意(在哪个源文件中都可以)但程序的运行 从主函数开始。如果主函数在调用函数前,要对调用函数进 行声明,如果主函数在调用函数后,函数声明可以省略。 一、1.系统函数(库函数)需要在程序前包含头文件 2.用户自己定义的函数 二、1.有返回值函数(注意返回值的类型) 2.无返回值函数(函数类型应定义为空类型void) 4.2.1函数的分类 三、1.无参函数。在调用无参函数时,主调函数不向被调 用函数传递数据。无参函数一般用来执行指定的一组操作 2.有参函数。在调用函数时,主调函数在调用被调用函 数时,通过参数向被调用函数传递数据,一般情况下,执行 被调用函数时会得到一个函数值,供主调函数使用。 4.2.2 4.2.2 函数定义函数定义 1. 1. 无参函数的定义一般形式无参函数的定义一般形式 定义无参函数的一般形式为: 类型说明符 函数名() 说明语句部分; 可执行语句部分; 在定义函数时要用 “类型说明符”指 定函数值的类型, 即函数带回来的值 的类型。例中的 printstar和 print_message函数 为void类型,表示 不需要带回函数值 为函数首部 (函数头) 内为函数 体 2. 2. 有参函数定义的一般形式有参函数定义的一般形式 定义有参函数的一般形式为: 类型说明符 函数名(形式参数表) 说明语句部分; 可执行语句部分; 例2: Int max(int ,int ) int ; / *函数体中的声明部分* ?; return(); 形式参数表简称形参 表,多个形参之间用 逗号分隔 形参是变量,必须进 行类型说明 3 .3 .空函数空函数 定义空函数的一般形式为: 类型说明符 函数名() 例如: void dm() 调用此函数时,什么工 作也不做,没有任何实 际作用。在主调函数中 写上“dm();”表明 “这里要调用一个函数 ”,而现在这个函数没 有起作用,等以后扩充 函数功能时补充上。 括号不能省略 4.2.34.2.3函数参数和函数的值函数参数和函数的值 1. 1.形式参数和实际参数形式参数和实际参数 形式参数:将函数定义中的参数表称为形式参数表,简称形参表 。与调用函数提供的实际参数区别。 实际参数:调用有参函数时,调用函数必须赋予这些参数实际的 值,调用函数中的参数称为实际参数。实参可以为变量,常量,函数 ,表达式,但实参要按照形参的类型和个数对应排列。 当函数调用时,调用函数把实参的值一一对应的传送给被调用函 数的形参,从而实现调用函数向被调用函数的数据传送。 形参出现在函数定义中,只能在该函数体内使用(有效),调用 结束,返回调用函数后,不能在使用形参变量。 #include void main( ) int max(int ,int );/* 对对max函数的声明 */ int ,; scanf(,); max(,); printf(“max is ,); int max(int ,int ) int ; ?; return(); 例例2 2: 实参与形参的类型 应相同或赋值兼容 ;如果a=3.5则形参 x=3 字符型和整形通用 运行情况如下: , max is 通过函数调用,使两个函数中的数据发生联系 关于形参与实参的说明: (1) 在定义函数中指定的形参,在未出现函数调用时,它 们并不占内存中的存储单元。只有在发生函数调用时,函 数max中的形参才被分配内存单元。在调用结束后,形参 所占的内存单元也被释放。 (2) 实参可以是常量、变量或表达式,如: (,); 但要求它们有确定的值。在调用时将实参的值赋给形参。 (3) 在被定义的函数中,必须指定形参的类型(见例2 程序中的 “max(,);” )。 (4) 实参与形参的类型应相同或赋值兼容。例中实 参和形参都是整型。如果实参为整型而形参x为实型,或 者相反,则按不同类型数值的赋值规则进行转换。 例如实参值a为3.5,而形参x为整型,则将实数3.5转换成整数3, 然后送到形参x。字符型与整型可以互相通用。 (5) 在语言中,实参向对形参的数据传递是“值传递”,单向传递,只由实参 传给形参,而不能由形参传回来给实参。在内存中,实参单元与形参单元是不同 的单元。 图一 在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束 后,形参单元被释放,实参单元仍保留并维持原值。因此,在执行一个被调用函 数时,形参的值如果发生改变,并不会改变主调函数的实参的值。例如,若在执 行函数过程中和的值变为和,而和仍为和。图二 图一图二 4.3 4.3 函数的返回值函数的返回值 通常,希望通过函数调用使主调函数能得到一个确定的值, 这就是函数的返回值。例如,例中,max(2,3)的值 是,max(,)的值是5。赋值语句将这个函数值赋给 变量。 关于函数返回值的一些说明: (1)函数的返回值是通过函数中的return语句获得的。 如果需要从被调用函数带回一个函数值供主调函数使用 ,被调用函数中必须包含return语句。如果不需要从被调 用函数带回函数值可以不要return语句。 一个函数中可以有一个以上的return语句,执行到哪一个 return语句,哪一个语句起作用,函数结束,所以函数只 能返回一个值。return语句后面的括弧也可以不要 如: “return ;” 等价于 “return ();” return语句将被调用函数中的一个确定值带回主调函数 中去。 return后面的值可以是一个表达式。 例如,例中的函数max可以改写成: max(int ,int ) return(?); (2) 函数的返回值应当属于某一个确定的类型,在定义函 数时指定函数返回值的类型。 例如:下面是3个函数的首行: int max(float ,float ) /* 函数值为整型 */ char letter(char c1,char c2) /* 函数值为字符型 */ double min(int ,int ) /* 函数值为双精度型 */ 在语言中,凡不加类型说明的函数,自动按整型处理 。例中的max函数首行的函数类型int可以省写,用 Turbo C 2.0编译程序时能通过,但用Turbo C 3.0 编译程序时不能通过,因此,建议在定义时对所有函数都 指定函数类型。 其中:int char double为函数类型,实质上函数类型就是 函数返回值的类型,就是return语句返回数据的类型。 (3)在定义函数时指定的函数类型一般应该和return语 句中的表达式类型一致。 如果函数值的类型和return语句中表达式的值不一致,则 以函数类型为准。对数值型数据,可以自动进行类型转换 。即函数类型决定返回值的类型。 (4)对于不带回值的函数,应当用“void”定义函数为 “无类型”(或称“空类型”)。这样,系统就保证不使 函数带回任何值,即禁止在调用函数中使用被调用函数的 返回值。此时在函数体中不得出现return语句。 例 返回值类型与函数类型不同 # include void main() int max(float ,float ); 函数声明 float ,; int ; scanf(,); max(,); printf(“max is ,); int max(float ,float ) float ; /* z为实型变量 */ ?; return(); 运行情况如下: 1.5, 2.5 max is 4.3 4.3 函数的调用函数的调用 函数调用的一般形式函数调用的一般形式 函数调用的一般形式为: 函数名(实参表) 如果实参表列包含多个实参,则各参数间用逗号隔开 。实参与形参的个数应相等,类型应匹配。实参与形 参按顺序对应,一一传递数据。 如果是调用无参函数,则“实参表”可以没有,但括弧 不能省略。 例 实参求值的顺序 #include void main() int f(int a,int b); /* 函数声明 */ int i=2,p; p=f(i,+i); /* 函数调用 */ printf(“%dn“,p); int f(int a,int b) /函数定义 */ int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return(c); 如果按自左至右顺序求实参的 值,则函数调用相当于( ,) 如果按从右至左顺序求实参的值, 则函数调用相当于(3,) 一般选择从右至左。结果为:0 对于函数调用 int i=2,p; p=f(i,+i); 4.3.4.3.函数调用的方式函数调用的方式 函数语句 把函数调用作为一个语句。如例1中的printstar();这时不 要求函数带回值,只要求函数完成一定的操作。 函数表达式 函数出现在一个表达式中,这种表达式称为函数表达式。 这时要求函数带回一个确定的值以参加表达式的运算。例 如:*max(,); 按函数在程序中出现的位置来分,可以有三种调用方式 函数参数 函数调用作为一个函数的实参。例如: m = max (a , max ( b , c ) ) ; 其中max ( b , c )是一次函数调用,它的值作为max另一次 调用的实参。m的值是a、b、c三者中的最大者。又如: printf (“%d“, max (a,b);也是把max ( a , b )作为printf函 数的一个参数。 函数调用作为函数的参数,实质上也是函数表达式形 式调用的一种,因为函数的参数本来就要求是表达式形式 。 4.3.34.3.3对被调用函数的声明和函数原型对被调用函数的声明和函数原型 在一个函数中调用另一个函数需要具备哪些条件: 被调用函数已经存在(库函数或用户自定义); 使用库函数或别的文件中的函数,应该在本文件开头用 #include命令将有关的编译预处理信息包含到本文件中来。 例: 使用输入输出函数 #include “stdio.h” 使用数学函数 #include “math.h” 若使用用户自己定义的函数,而且该函数与主调函数在同一 个文件中,则需在主调函数中对被调用的函数进行说明。 说明形式 类型名 函数名(类型1 变量1,类型n 变量n ); 函数原型的一般形式为 (1) 函数类型 函数名(参数类型1,参数类型2); (2) 函数类型 函数名(参数类型1,参数名1,参数类型2 ,参数名2); 声明的作用是把函数名、函数参数的个数和参数类型等信 息通知编译系统,以便在遇到函数调用时,编译系统能正 确识别函数并检查调用是否合法。 (例如函数名是否正 确,实参与形参的类型和个数是否一致)。 # include void main() int max(float ,float ); 函数原型声明 float ,; int ; scanf(,); max(,); printf(“max is ,); int max(float ,float ) float ; /* z为实型变量 */ ?; return(); # include void main() float add(float x, float y); *对被调用函数add的声明* float a,b,c; scanf(f,f,a,b); cadd(a,b); printf(sum is f n,c); float add(float ,float ) *函数首部* float ; /* 函数体 */ z; return(z); 例 对被调用的函数作声明 如果 被调用函数的定义出现在主调函数之前,可以不必加以声明。 改写例 # include float add(float ,float ) *函数首部* float ; /* 函数体 */ z; return(z); void main() float a,b,c; scanf(f,f,a,b); cadd(a,b); printf(sum is f n,c); 由于:函数add写在 主函数之前,可以 在主函数中省略对 add函数的声明 4.4 4.4 函数的嵌套调用函数的嵌套调用 1、 被调函数在调用过程中,调用其他函数称为函 数的嵌套调用。 2、 函数可以嵌套调用,不允许嵌套定义。 一个函数不能定义在其他函数的内 部,函数之间是互相独立的,是平 行的 函数的外部性 嵌套调用函数执行情况如图所示 mainmain函数函数 调用函调用函数数 A;A; 函数函数 A A 调用函数调用函数B B; 函数函数 B B 例6:计算s的值 #include long int f1(int n, int k) 计算n的k次方 long int power=1; int i; for(i=1;i1) 求n!与求(n-1)!的方法是一样的,只是参数值不同。 long fac( int n) long f ; if(n=0) f=1; /*递归结束条件*/ else f=n*fac(n-1); /*直接递归调用*/ return f; main( ) long y; int n; scanf(“%d”, y = fac(n); printf(“%d!=%ld”, n, y); 例7:用递归方法求! 当输入3时,函数调用过程如下: 回推阶段 main() fac函数 fac函数 fac函数 fac函数 n=3 n=2 n=1 n=0 fac(3) fac(2) fac(1) fac(0) y=fac(3) f=3*fac(2) f=2*fac(1) f=1*fac(0) f=1 6 2 1 1 return(f) return(f) return(f) return(f) 输出:3!=6 递推阶段 fac函数在回推阶段被调用了4次,递归调用了3次,到终止条 件n=0时才有确定的值,然后再递推出每一次调用的值,最后得到 所求的结果。 例 8 有个人坐在一起,问第个人多少岁?他说比 第个人大岁。问第个人岁数,他说比第个人大 岁。问第个人,又说比第个人大岁。问第个人, 说比第个人大岁。最后问第个人,他说是岁。 请问第个人多大。 age()age() age()age() age()age() age()age() age()10 可以用数学公式表述如下: age() () age(-) () 可以用一个函数来描述上述递归过程: int age(int ) * 求年龄的递归函数 * int ; * 存放函数的返回值的变量 * if(=1) =10; else =age(n-1); return(); 用一个主函数调用age函数,求得第5人的年龄。 #include void main() printf(,age(); 运行结果如下: 18 例8:斐波那契数列:1,1,2,3,5,8,13,21, #include int fibonacci(int n) if(n long int gys (int x,int y) if(x%y=0) return y; else return gys(y, x%y); void main( ) int a,b; scanf(“%d,%d”, printf(“%dn”,gys(a,b); C语言中的变量: v1、数据类型 v2、作用域 由变量定义的位置决定 局部变量和全局变量 v3、生命期 由变量在内存中的储存方式决定 静态存储类和动态存储类 4.64.6局部变量和全局变量局部变量和全局变量 4.6.14.6.1局部变量局部变量 在一个函数内部定义的变量是内部变量,它只在 本函数范围内有效,也就是说只有在本函数内才 能使用它们,在此函数以外是不能使用这些变量 的。这称为“局部变量”。 float f1( int a) /* 函数f1 */ int b,c; b、c有效 char f2(int x,int y) /* 函数f2 */ int i,j,b; x、y、i、j, b有效 void main( ) /* 主函数 */ int m,n; m、n有效 (1) 主函数中定义的变量(m,n)也只在主函数中有效(使用),而不因为 在主函数中定义而在整个文件或程序中有效。主函数也不能使用 其他函数中定义的变量。 (2) 不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干 扰。例如, 上面在f1函数中定义了变量b和c,倘若在f2函数中也定义变量 b和c,它们在内存中占不同的单元,互不混淆。 (3) 形式参数也是局部变量。例如上面f1函数中的形参a,也只在f1函数 中有效。其他函数可以调用f1函数,但不能引用f1函数的形参a。 (4) 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合 语句中有效,这种复合语句也称为“分程序”或“程序块”。 说明 习题5 void main ( ) int i=1,j=3; printf(“%d”,i+); int i=0; i+=j*2; printf(“%d,%d”,i,j); i=0在复合语句范围内有效 printf(“%d,%dn”,i,j); i=1在复合语句之外范围内有效 输出结果:1,6,3,2,3 4.6.2 4.6.2 全局变量全局变量 在函数内定义的变量是局部变量,而在函数之外定 义的变量称为外部变量,外部变量是全局变量(也 称全程变量)。全局变量可以为本文件中其他函数 所共用。它的有效范围为从定义变量的位置开始 到本源文件结束。 注意:同一文件中,允许全局变量同名,在局 部变量的作用域内,全局变量不起作用。 int p=1,q=5; /*p和q 全局(外部)变量 */ float f1(int a) /* 定义函数f1 */ int b,c; char c1,c2; /* c1,c2全局(外部)变量 */ char f2 (int x, int y) /* 定义函数f2 */ int i,j; void main ( ) /* 主函数 */ int m,n; 全 局 变 量 p q 的 作 用 范 围 全 局 变 量 c1 c2 的 作 用 范 围 4.7 4.7 变量的存储类别变量的存储类别 4.7.1 4.7.1 动态存储方式与静态存储方式动态存储方式与静态存储方式 前面已介绍了从变量的作用域(即从空间)角度来分,有 全局变量和局部变量。那么从变量值存在的时间(即生存 期)

温馨提示

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

评论

0/150

提交评论