资源预览内容
第1页 / 共63页
第2页 / 共63页
第3页 / 共63页
第4页 / 共63页
第5页 / 共63页
第6页 / 共63页
第7页 / 共63页
第8页 / 共63页
第9页 / 共63页
第10页 / 共63页
亲,该文档总共63页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
2019/5/25,1,第7章 函数与变量作用域,C语言是通过函数来实现模块化程序设计的。 教学目的: 掌握函数的定义与调用,变量的作用域; 了解函数的嵌套与递归调用,内部、外部函数特点,以及变量的存储特性。,2019/5/25,2,教学内容: 7.1* 函数的定义与调用 7.2 函数的嵌套调用与递归调用 7.3 内部函数与外部函数 7.4* 内部变量与外部变量 7.5 变量的存储特性 本章要点 本章作业与上机实践,2019/5/25,3,7.1* 函数定义与函数调用,7.1.1 函数定义 任何函数都是由函数说明和函数体两部分组成。 1分类 根据函数有无参数,将函数分为无参函数和有参函数。,2019/5/25,4,(1)无参函数 函数类型 函数名( void ) 说明语句部分; 可执行语句部分; (2)有参函数 函数类型 函数名(数据类型 参数,数据类型 参数2 ) 说明语句部分; 可执行语句部分; ,形参表。调用有参函数时,由调用函数为形参提供实际值,简称为实参。,在新标准中,函数不可缺省参数表;用“void”表示不需要参数。,2019/5/25,5,2函数的返回值与函数类型 语言的函数,还可分为有返回值函数和无返回值函数两种。 (1) 有返回值函数与return语句 一般格式: return( 返回值表达式 ); 功能:返回调用函数,并将“返回值表达式”的值带给调用函数。 注意:函数中无return语句,返回1个不确定的值。可用“void”定义成“无(空)类型” ,明确表示不返回值 。,括号可以缺省,2019/5/25,6,(2) 函数类型 函数类型应与return语句中“返回值表达式”的类型一致。 如果不一致,则以函数类型为准。 如果缺省函数类型,则系统一律按int型处理。 良好的程序设计习惯: 为了使程序具有良好的可读性并减少出错,将无返回值函数定义为空类型void; 同时,也不使用系统对函数类型的缺省处理。,2019/5/25,7,案例7.1 定义一个求两个整数中极大值的max()函数。 /*功能:求2个整数中的较大数 */ /*形参:2个,整型 */ /*返回值: 2个整数中的较大数 */ int max( int n1, int n2) /*函数定义 */ return ( n1 n2 ? n1 : n2); /*/ void main( void ) int max(int n1, int n2); /*对被调用函数进行说明*/ int num1,num2; printf(“input two numbers: “); scanf(“%d%d“, &num1, &num2); printf(“max=%dn“, max(num1, num2); ,2019/5/25,8,3、说明 (1)函数定义不允许嵌套。 一个函数的定义,可以放在程序中的任意位置,但不能在另一个函数的函数体内,即不能嵌套定义。 例如:main( ) int max() (2)空函数函数体为空的无参函数: 函数类型 函数名( void ) ,2019/5/25,9,7.1.2 函数调用与返回 1、对被调用函数的说明和函数原型 (1) 函数说明的一般格式 在新标准中,采用函数原型方式,对被调用函数进行说明: 函数类型 函数名(形参表);,2019/5/25,10,(2) 函数说明的两种方式 谁调用谁说明:函数说明语句放在调用函数的函数体中。 例如,在案例7.1主函数main()中: void main( void ) int max( int n1, int n2); ,对被调用函数进行说明,2019/5/25,11,预先统一说明函数说明通常放在所有函数定义体之前。 在这种方式下,所有调用函数都无需再对自定义函数进行说明。 例如,在案例7.1中,可以将对max()函数的说明放在程序文件开始处: void main( void ) int max(int n1, int n2); ,2019/5/25,12,显然,对于被多个函数调用的自定义函数而言,采用预先统一说明方式进行说明,可以有效地减少函数说明次数。 注意: 如果被调用函数的定义体,出现在调用函数之前,可以缺省说明。,2019/5/25,13,2、函数调用 函数名(实参表) 例如,在案例7.1的主函数中: printf(, max (num1, num2) ); 注意:调用有参函数,必须提供实参(常量/变量/表达式/函数) 。调用时,实参必须具有确定的值,且与形参个数相等、类型匹配。,2019/5/25,14,(1) 调用方式 语句方式无返回值函数的调用,可作为一条独立的语句。 例如,printf()、scanf ()等库函数的调用,均作为一条独立的语句。 表达式方式有返回值函数作为表达式的一项,以函数返回值参与表达式的运算。 例如,“max = max(x, y)”是一个赋值表达式,把max()函数的返回值赋予变量max。,2019/5/25,15,(2) 断点与函数调用的返回 断点被调用函数执行完毕,返回调用函数后继续执行的位置。 调用函数中的断点位置分两种情况: 语句调用方式:断点为函数调用语句的下一条语句。 例如,案例7.1中的语句调用“printf();”,其断点为该语句的下一条语句“getch();” 。,2019/5/25,16, 表达式调用方式:断点为函数调用所在的表达式。 例如,在案例7.1中,“printf(, max(num1, num2) );”语句中的表达式调用“max(num1, num2)”: 其断点为该表达式调用所在的表达式“max(num1, num2)”(在本例中,“max(num1, num2)”函数调用既是表达式调用,本身又构成一个简单表达式)。,2019/5/25,17,7.1.3 参数传递 发生函数调用时,根据参数值的性质不同,将参数传递分为两种: (1) 值传递参数值是一个一般数据(整形、实型、字符型数据等)。 系统把实参值复制1份给形参;被调用函数结束时,形参值不能传回给实参。 (2) 地址(引用)传递参数值是一个地址。,2019/5/25,18,执行案例7.1时的参数传递: int max( int n1, int n2) return ( n1 n2 ? n1 : n2); main( ) int max(int n1, int n2); int num1,num2; printf(“input two numbers: “); scanf(“%d%d“, &num1, &num2); printf(“max=%dn“, max(num1, num2); ,2019/5/25,19,(1)形参变量只有在被调用时,才分配内存单元;调用结束时,立即被释放。 因此,形参只有在该函数内有效。调用结束,返回调用函数后,则不能再使用该形参变量。 (2)实参和形参占用不同的内存单元,即使同名也互不影响。,2019/5/25,20,7.1.4 小结 1函数定义不允许嵌套。 2调用有参函数时,实参的个数和类型,必须与形参匹配。 3 函数调用的两种方式与断点位置 (1) 语句方式:断点为函数调用语句的下一条语句。 (2) 表达式方式:断点为函数调用所在的表达式。,2019/5/25,21,4参数传递分两种: (1) 值传递:单向传递。 (2) 地址(引用)传递。 返回,2019/5/25,22,7.2 函数的嵌套调用和递归调用,7.2.1 函数的嵌套调用 案例7.3 计算 = 1!+2!+ + n!(n1,20的整数,从键盘输入)。 算法设计要点: 本案例可以设计2个函数:factor( )用于求n!;sum( )通过调用factor( )来实现求。 程序框架如下(完整程序详见教材7.2.1):,2019/5/25,23, void main( ) sum( num ); /*调用函数sum( )*/ void sum(int num) sum += factor (loop); /*求累计和*/ long factor (int num) /*求num的阶乘*/ ,2019/5/25,24,在案例7.3中,主函数main()调用求和函数sum( ),sum( ) 又循环调用求阶乘的函数factor( )。 一般地说,函数的嵌套调用是指,在执行被调用函数时,该函数又调用其它函数的情形。 注意:被调用函数执行完毕后,将返回到调用函数的断点继续执行。 简言之,谁调用,返回到谁的断点继续执行。,2019/5/25,25,7.2.2 函数的递归调用 案例7.4 用递归法计算n!(1! = 1,n! = (n-1)! * n (n2))。 算法设计要点: (1) 根据计算n!的递归定义可知,为了计算n!,必须首先计算(n-1)!;以此类推,直至1!(1! = 1)。 (2) 依据1!求2!=1!*2,再依据2!求3!=2!*3;同理,依据(n-1)!求n!= (n-1)!*n。,2019/5/25,26,long factor( int num ) long fact; if( num 1) fact = factor( num 1 ) * num; else fact = 1; return( fact ); 以num = 5为例,其执行过程详见教材7.2.2。,递归调用自己,2019/5/25,27,语言允许函数直接(或间接)地调用它自己,称为递归调用;这种函数称为递归函数。 例如,案例7.4中的函数factor()就是一个递归函数。 防止递归调用无终止地进行的常用办法:添加1个继续(或终止)递归调用的条件判断。 例如,案例7.4中函数factor( )中的“if( num 1)” 。 返回,2019/5/25,28,7.3 内部函数和外部函数,C语言程序中的函数,是通过被调用而执行的,所以一个函数需要被其它函数调用。 但是,当一个程序由多个源文件组成时,在一个源文件中定义的函数,能否被其它源文件中的函数调用呢? 语言据此将函数分为内部函数和外部函数。,2019/5/25,29,7.3.1 内部函数(又称静态函数) 如果在一个源文件中定义的函数,只能被本源文件中的其它函数调用,这种函数称为内部函数。 1定义 static 函数类型 函数名(形参表) 2 特点:只能被本文件中的函数所调用。 3 好处:不用担心与其它源文件中的函数同名,因为即使同名也没关系。,2019/5/25,30,7.3.2 外部函数 如果在某源文件中定义的函数,可被同一程序中所有源文件中的函数调用,这种函数称为外部函数。 1定义:extern 函数类型 函数名( 形参表 ) 2特点:允许被所有源文件中的函数所调用。 3调用其它源文件中的外部函数时,需要对其进行说明: extern 函数类型 函数名(形参表),函数名2(形参表2 );,2019/5/25,31,案例7.5 将加、减、乘、除和求余数运算练习程序(第3版)的源文件组织形式改为:实现加、减、乘、除和求余数运算的程序段,均作为1个独立的函数、存储在1个独立的源文件中。 程序框架如下(完整程序详见案例源代码):,2019/5/25,32, /*外部函数说明*/ extern void addition(int n1, int n2); extern void subtraction(int n1, int n2); extern void multiplic
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号