(6.14)--补充课件第08讲-函数程序设计基础.ppt
第八讲函数第八讲函数C语言程序设计语言程序设计 The C Programming Language2C语言程序设计语言程序设计 温州理工学院温州理工学院 2第八讲第八讲 函数函数本章要求本章要求理解模块化程序设计思想;理解模块化程序设计思想;掌握函数的定义与调用方法;掌握函数的定义与调用方法;掌握掌握C语言的参数传递方式,尤其是数组参数的传递特点;语言的参数传递方式,尤其是数组参数的传递特点;掌握变量的作用域和存储方式。掌握变量的作用域和存储方式。本章重点本章重点函数的定义与调用函数的定义与调用参数传递参数传递变量的作用域和存储方式变量的作用域和存储方式本章难点本章难点参数传递参数传递变量的作用域和存储方式变量的作用域和存储方式3C语言程序设计语言程序设计 温州理工学院温州理工学院 3第八讲第八讲 函数函数概述概述函数的定义函数的定义函数调用与参数传递函数调用与参数传递函数的嵌套调用与递归调用函数的嵌套调用与递归调用数组作为函数参数数组作为函数参数局部变量与全局变量局部变量与全局变量变量的存储类别变量的存储类别内部函数与外部函数内部函数与外部函数程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间4C语言程序设计语言程序设计 温州理工学院温州理工学院 4第八讲第八讲 函数函数概述概述函数的定义函数的定义函数调用与参数传递函数调用与参数传递函数的嵌套调用与递归调用函数的嵌套调用与递归调用数组作为函数参数数组作为函数参数局部变量与全局变量局部变量与全局变量变量的存储类别变量的存储类别内部函数与外部函数内部函数与外部函数程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间5C语言程序设计语言程序设计 温州理工学院温州理工学院 5程序设计方法程序设计方法结构化设计结构化设计方法方法模块内部程序各部分要按照自顶向下的结构划模块内部程序各部分要按照自顶向下的结构划分分各程序部分应按功能组合各程序部分应按功能组合各程序之间的联系尽量通过调用子程序来实现,各程序之间的联系尽量通过调用子程序来实现,不用或少用不用或少用GOTO方式方式快速原型方法快速原型方法利用现有的工具和原型方法快速地开发所要的利用现有的工具和原型方法快速地开发所要的程序程序面向对象程序设计方法面向对象程序设计方法6C语言程序设计语言程序设计 温州理工学院温州理工学院 6C语言结构化程序设计方法语言结构化程序设计方法#include#define NAME Wenzhou University#define ADDRESS Wenzhou 325035#define NATION P.R.China void line(void);/*声明函数原型声明函数原型*/main()line();/*调用函数调用函数*/printf(%sn,NAME);printf(%sn,ADDRESS);printf(%sn,NATION);line();/*调用函数调用函数*/void line(void)/*定义函数定义函数*/printf(=n);7C语言程序设计语言程序设计 温州理工学院温州理工学院 7C语言结构化程序设计方法语言结构化程序设计方法 8C语言程序设计语言程序设计 温州理工学院温州理工学院 8函数概述函数概述函数函数是是C源程序的源程序的基本模块基本模块,通过对函数模块的调用,通过对函数模块的调用实现特定的功能。可以说实现特定的功能。可以说C程序的全部工作都是由各程序的全部工作都是由各式各样的函数完成式各样的函数完成的。的。C语言不仅提供了极为丰富的库函数语言不仅提供了极为丰富的库函数(如如Turbo C,MS C 都都提供了三百多个库函数提供了三百多个库函数),还允许用户建立自己定义的函数。,还允许用户建立自己定义的函数。从从使用角度划分使用角度划分 标准函数,即库函数标准函数,即库函数 自定义函数自定义函数 从函数形式划分从函数形式划分 无参函数无参函数 有参函数有参函数 9C语言程序设计语言程序设计 温州理工学院温州理工学院 9函数概述函数概述(contd)从函数定义的角度看,函数可分为从函数定义的角度看,函数可分为库函数库函数和和用用户定义函数户定义函数两种。两种。库函数库函数:由由C系统系统提供,用户无须定义,也不必在提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。型的头文件即可在程序中直接调用。如如printf、scanf、getchar、putchar、gets、puts、strcat 等函数均属此类。等函数均属此类。用户定义函数用户定义函数:由用户按需要写的函数。对于用户:由用户按需要写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而且自定义函数,不仅要在程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。明,然后才能使用。10C语言程序设计语言程序设计 温州理工学院温州理工学院 10函数概述函数概述(contd)C语言的函数兼有其它语言中的语言的函数兼有其它语言中的函数函数和和过程过程两种功两种功能。因此,函数又可分为能。因此,函数又可分为有返回值函数有返回值函数和和无返回无返回值函数值函数两种。两种。有返回值函数有返回值函数:被调用执行完后将向调用者返回一个:被调用执行完后将向调用者返回一个执行结果,称为函数返回值。执行结果,称为函数返回值。如数学函数即属于此类函数。由用户定义的有返回值的函数,如数学函数即属于此类函数。由用户定义的有返回值的函数,必须在函数定义和函数说明中明确返回值的类型。必须在函数定义和函数说明中明确返回值的类型。无返回值函数无返回值函数:用于完成某项特定的处理任务,执行:用于完成某项特定的处理任务,执行完成后不向调用者返回函数值。完成后不向调用者返回函数值。这类函数类似于其它语言的过程。这类函数类似于其它语言的过程。用户在定义此类函数时可指定它的返回为用户在定义此类函数时可指定它的返回为“空类型空类型”,空类空类型的说明符为型的说明符为“void”。11C语言程序设计语言程序设计 温州理工学院温州理工学院 11函数概述函数概述(contd)从主调函数和被调函数之间数据传送的角度看从主调函数和被调函数之间数据传送的角度看又可分为又可分为无参函数无参函数和和有参函数有参函数两种。两种。无参函数无参函数:函数定义、函数说明及函数调用中均不:函数定义、函数说明及函数调用中均不带参数。主调函数和被调函数之间不进行参数传送。带参数。主调函数和被调函数之间不进行参数传送。此类函数通常用来完成一组指定的功能,可以返回此类函数通常用来完成一组指定的功能,可以返回或不返回函数值。或不返回函数值。有参函数有参函数:也称为带参函数。在函数定义及函数说:也称为带参函数。在函数定义及函数说明时都有参数,称为形式参数明时都有参数,称为形式参数(简称为形参简称为形参)。在函。在函数调用时也必须给出参数,称为实际参数数调用时也必须给出参数,称为实际参数(简称为简称为实参实参)。进行函数调用时,主调函数将把实参的值。进行函数调用时,主调函数将把实参的值传送给形参,供被调函数使用。传送给形参,供被调函数使用。12C语言程序设计语言程序设计 温州理工学院温州理工学院 12函数概述函数概述(contd)C语言语言提供了极为丰富的库函数,这些库函数提供了极为丰富的库函数,这些库函数又可从功能角度作以下分类。又可从功能角度作以下分类。字符类型分类函数字符类型分类函数:用于对字符按ASCII 码分类:字母,数字,控制字符,分隔符,大小写字母等。转换函数转换函数:用于字符或字符串的转换;在字符量和各类数字量(整型,实型等)之间进行转换;在大、小写之间进行转换。目录路径函数目录路径函数:用于文件目录和路径操作。诊断函数诊断函数:用于内部错误检测。图形函数图形函数:用于屏幕管理和各种图形功能。13C语言程序设计语言程序设计 温州理工学院温州理工学院 13函数概述函数概述(contd)输入输出函数输入输出函数:用于完成输入输出功能。接口函数接口函数:用于与DOS,BIOS 和硬件的接口。字符串函数字符串函数:用于字符串操作和处理。内存管理函数内存管理函数:用于内存管理。数学函数数学函数:用于数学函数计算。日期和时间函数日期和时间函数:用于日期,时间转换操作。进程控制函数进程控制函数:用于进程管理和控制。其它函数其它函数:用于其它各种功能。14C语言程序设计语言程序设计 温州理工学院温州理工学院 14函数概述函数概述(contd)在在C语言语言中,所有的函数定义,包括主函数中,所有的函数定义,包括主函数main 在内,都是在内,都是平行平行的。的。也就是说,在一个函数的函数体内,不能再定义另一也就是说,在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定义。个函数,即不能嵌套定义。但是函数之间允许相互调用,也允许嵌套调用。习惯但是函数之间允许相互调用,也允许嵌套调用。习惯上把调用者称为主调函数。函数还可以自己调用自己,上把调用者称为主调函数。函数还可以自己调用自己,称为递归调用。称为递归调用。main 函数是主函数,它可以调用其它函数,而不函数是主函数,它可以调用其它函数,而不允许被其它函数调用允许被其它函数调用。C程序的执行总是从程序的执行总是从main 函数开始,完成对其它函数函数开始,完成对其它函数的调用后再返回到的调用后再返回到main 函数,最后由函数,最后由main 函数结束整函数结束整个程序。一个个程序。一个C源程序必须有且只有一个主函数源程序必须有且只有一个主函数main。15C语言程序设计语言程序设计 温州理工学院温州理工学院 15第八讲第八讲 函数函数概述概述函数的定义函数的定义函数调用与参数传递函数调用与参数传递函数的嵌套调用与递归调用函数的嵌套调用与递归调用数组作为函数参数数组作为函数参数局部变量与全局变量局部变量与全局变量变量的存储类别变量的存储类别内部函数与外部函数内部函数与外部函数程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间16C语言程序设计语言程序设计 温州理工学院温州理工学院 16函数的定义函数的定义函数定义的一般形式函数定义的一般形式其中类型标识符和函数名称为函数头。类型标识符其中类型标识符和函数名称为函数头。类型标识符指明了本函数的类型,函数的类型实际上是函数返指明了本函数的类型,函数的类型实际上是函数返回值的类型。回值的类型。函数名是由用户定义的标识符,函数名后有一个空函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少。括号,其中无参数,但括号不可少。中的内容称为函数体。在函数体中声明部分,是中的内容称为函数体。在函数体中声明部分,是对函数体内部所用到的变量的类型说明。对函数体内部所用到的变量的类型说明。类型符类型符 函数名函数名(形式参数形式参数)函数体函数体 17C语言程序设计语言程序设计 温州理工学院温州理工学院 17函数的定义函数的定义在很多情况下都不要求无参函数有返回值,此在很多情况下都不要求无参函数有返回值,此时函数类型符可以写为时函数类型符可以写为void。类型符使用类型符使用C语言提供的数据类型标识符,用语言提供的数据类型标识符,用于说明函数返回值的类型于说明函数返回值的类型。函数名是一个标识符,应当遵循函数名是一个标识符,应当遵循C语言中标识语言中标识符的命名规则符的命名规则。void Hello()printf(Hello,world n);18C语言程序设计语言程序设计 温州理工学院温州理工学院 18函数的定义函数的定义形式参数可以是形式参数可以是0个、一个或多个,表示该函个、一个或多个,表示该函数被调用时所需的一些必要信息。数被调用时所需的一些必要信息。对于有参函数,形式参数的定义与变量的定义对于有参函数,形式参数的定义与变量的定义形式相似形式相似。函数体是一组放在一对花括号中的语句函数体是一组放在一对花括号中的语句,一般一般包括声明部分和执行部分包括声明部分和执行部分。在函数中,形式参数可以作为已知的变量,不在函数中,形式参数可以作为已知的变量,不需要对它赋值就可使用它,它的值是函数调用需要对它赋值就可使用它,它的值是函数调用时由实参传递给形参变量而得到的时由实参传递给形参变量而得到的。19C语言程序设计语言程序设计 温州理工学院温州理工学院 19有参函数定义的一般形式有参函数定义的一般形式有参有参函数比无参函数多了一个内容,即形式参数表函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数列。在形参表中给出的参数称为形式参数,它们,它们可可以是各种类型的变量,各参数之间用逗号间隔。在以是各种类型的变量,各参数之间用逗号间隔。在进行函数调用时,主调函数将进行函数调用时,主调函数将赋予这些赋予这些形式参数实形式参数实际的值。形参既然是变量,必须在形参表中给出形际的值。形参既然是变量,必须在形参表中给出形参的类型说明。参的类型说明。类型标识符类型标识符 函数名函数名(形式参数表列形式参数表列)声明部分声明部分 语句语句20C语言程序设计语言程序设计 温州理工学院温州理工学院 20函数的定义函数的定义函数返回值函数返回值C语语言言通通过过return语语句句获获得得函函数数返返回回值值的的,其其格格式式如下:如下:return 表达式表达式;或或 return(表达式表达式);定义一个函数,用于求两个整数定义一个函数,用于求两个整数中的大数,可写为:中的大数,可写为:int max(int a,int b)if(ab)return a;else return b;21C语言程序设计语言程序设计 温州理工学院温州理工学院 21函数的定义函数的定义main()int max(int a,int b);int x,y,z;printf(Input two integers:n);scanf(%d%d,&x,&y);z=max(x,y);printf(MaxNum=%d,z);int max(int a,int b)if(ab)return a;else return b;第一行说明第一行说明max 函数是一个整函数是一个整型函数,其返回的函数值是一个型函数,其返回的函数值是一个整数。整数。形参为形参为a,b,均为整型量。均为整型量。a,b 的的具体值是由主调函数在调用时传具体值是由主调函数在调用时传送过来的。送过来的。在在中的函数体内,除形参外中的函数体内,除形参外没有使用其它变量,因此只有语没有使用其它变量,因此只有语句而没有声明部分。句而没有声明部分。在在max 函数体中的函数体中的return 语句语句是把是把a(或或b)的值作为函数的值返的值作为函数的值返回给主调函数。有返回值函数中回给主调函数。有返回值函数中至少应有一个至少应有一个return 语句。语句。22C语言程序设计语言程序设计 温州理工学院温州理工学院 22函数的定义函数的定义说明:说明:表达式的值即函数返回值,它应与所定义的函数返表达式的值即函数返回值,它应与所定义的函数返回值的类型一致。回值的类型一致。23C语言程序设计语言程序设计 温州理工学院温州理工学院 23Return语句语句不带表达式的不带表达式的return语句将把控制权返回给调语句将把控制权返回给调用者,但不返回有用的值。这时用者,但不返回有用的值。这时return语句的语句的作用是终止执行函数。作用是终止执行函数。#include stdio.hmain()return;printf(Hello,world!n);return 0;24C语言程序设计语言程序设计 温州理工学院温州理工学院 24Return语句语句由于由于main本身也是函数,因此也可以向其调用本身也是函数,因此也可以向其调用者返回一个值,该调用者实际上就是程序的执者返回一个值,该调用者实际上就是程序的执行环境。行环境。一般来说,返回值为一般来说,返回值为0表示正常终止,返回值表示正常终止,返回值为非为非0表示出现异常情况或出错结束条件。表示出现异常情况或出错结束条件。#include stdio.hmain()printf(Hello,world!n);getch();return 0;25C语言程序设计语言程序设计 温州理工学院温州理工学院 25函数的参数和函数的值函数的参数和函数的值函数的参数分为函数的参数分为形参形参和和实参实参两种两种。形参形参和实参的功能是作和实参的功能是作数据传送数据传送。发生函数调。发生函数调用时,主调函数把实参的值传送给被调函数的用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。形参从而实现主调函数向被调函数的数据传送。形参形参出现在函数定义中,在整个函数体内都可以使出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。用,离开该函数则不能使用。实参实参出现在主调函数中,进入被调函数后,实参变出现在主调函数中,进入被调函数后,实参变量也不能使用量也不能使用。26C语言程序设计语言程序设计 温州理工学院温州理工学院 26函数的参数和函数的值函数的参数和函数的值函数函数的形参和实参具有以下特点:的形参和实参具有以下特点:形参形参变量只有在被调用时才分配内存单元,在调用变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参结束时,即刻释放所分配的内存单元。因此,形参只有在只有在函数内部函数内部有效。函数调用结束返回主调函数有效。函数调用结束返回主调函数后则不能再使用该形参变量后则不能再使用该形参变量。实参实参可以是常量、变量、表达式、函数等,无论实可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。应预先用赋值,输入等办法使实参获得确定值。实参实参和和形参形参在数量上、类型上应严格一致,否则会在数量上、类型上应严格一致,否则会发生发生“类型不匹配类型不匹配”的错误。的错误。27C语言程序设计语言程序设计 温州理工学院温州理工学院 27函数的参数和函数的值函数的参数和函数的值函数函数调用中发生的数据传送是调用中发生的数据传送是单向单向的。即只能把实的。即只能把实参的值传送给形参,而不能把形参的值反向地传送参的值传送给形参,而不能把形参的值反向地传送给实参。给实参。因此在函数调用过程中,形参的值发生因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。改变,而实参中的值不会变化。28C语言程序设计语言程序设计 温州理工学院温州理工学院 28函数的参数和函数的值函数的参数和函数的值main()int n;printf(“Input an integer:n);scanf(%d,&n);s(n);printf(n=%dn,n);int s(int n)int i;for(i=n-1;i=1;i-)n=n+i;printf(n=%dn,n);函数函数s的功能是求的功能是求ni的值。的值。形形参参变变量量和和实实参参变变量量的的标标识识符符都都为为n,但但这这是是两两个个不不同同的的量,各自的作用域不同。量,各自的作用域不同。若若输输入入n 值值为为100。即即实实参参n 的的值值为为100。把把此此值值传传给给函函数数s时时,形形参参n 的的初初值值也也为为100,在在执执行行函函数数过过程程中中,形形参参n 的的值值变变为为5050。返返回回主主函函数数之之后后,输输出出实实参参n 的的值值仍仍为为100。可可见见实实参参的的值值不不随随形形参参的的变变化化而而变化。变化。29C语言程序设计语言程序设计 温州理工学院温州理工学院 29函数的参数和函数的值函数的参数和函数的值函数的返回值函数的返回值:函数的值是指函数被调用之后,函数的值是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调执行函数体中的程序段所取得的并返回给主调函数的值。函数的值。函数的值只能通过函数的值只能通过return 语句返回主调函数。语句返回主调函数。return 语句的一般形式为:语句的一般形式为:该语句的功能是计算表达式的值,并返回给主该语句的功能是计算表达式的值,并返回给主调函数。在函数中允许有多个调函数。在函数中允许有多个return 语句,但语句,但每次调用只能有一个每次调用只能有一个return 语句被执行,因此语句被执行,因此只能返回一个函数值。只能返回一个函数值。return 表达式;表达式;30C语言程序设计语言程序设计 温州理工学院温州理工学院 30函数的参数和函数的值函数的参数和函数的值函数值的函数值的类型类型和函数定义中函数的类型应保持和函数定义中函数的类型应保持一致。如果两者不一致,则以函数类型为准,一致。如果两者不一致,则以函数类型为准,自动进行类型转换。如函数值为整型,在函数自动进行类型转换。如函数值为整型,在函数定义时可以省去类型说明。定义时可以省去类型说明。不返回函数值的函数,可以明确定义为不返回函数值的函数,可以明确定义为“空类空类型型”,类型说明符为,类型说明符为“void”。一旦函数被定义为空类型后,就不能在主调函数一旦函数被定义为空类型后,就不能在主调函数中使用被调函数的函数值了。为了使程序有良好中使用被调函数的函数值了。为了使程序有良好的可读性并减少出错,的可读性并减少出错,凡不要求返回值的函数都凡不要求返回值的函数都应定义为空类型。应定义为空类型。31C语言程序设计语言程序设计 温州理工学院温州理工学院 31第八讲第八讲 函数函数概述概述函数的定义函数的定义函数调用与参数传递函数调用与参数传递函数的嵌套调用与递归调用函数的嵌套调用与递归调用数组作为函数参数数组作为函数参数局部变量与全局变量局部变量与全局变量变量的存储类别变量的存储类别内部函数与外部函数内部函数与外部函数程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间32C语言程序设计语言程序设计 温州理工学院温州理工学院 32函数调用与参数传递函数调用与参数传递函数的调用方式函数的调用方式 有参函数调用的格式:有参函数调用的格式:函数名函数名(实际参数实际参数)无参函数的调用无参函数的调用格式:格式:函数名函数名()函数函数总是在某个函数体中被调用总是在某个函数体中被调用函函数数调调用用可可以以在在结结尾尾处处加加上上分分号号,单单独独作作为为一一条语句条语句对对于于有有返返回回值值的的函函数数,其其调调用用也也可可以以出出现现在在某某条语句中条语句中33C语言程序设计语言程序设计 温州理工学院温州理工学院 33函数调用与参数传递函数调用与参数传递函数的调用过程函数的调用过程34C语言程序设计语言程序设计 温州理工学院温州理工学院 34参数传递参数传递形式参数形式参数与与实际参数实际参数的区别的区别 形式参数形式参数又称为形参或虚参,它表示一个函数被调用又称为形参或虚参,它表示一个函数被调用时所需的一些必要信息。事实上,形参是一种局部变时所需的一些必要信息。事实上,形参是一种局部变量,它在函数被调用前并没有被分配存储空间,也没量,它在函数被调用前并没有被分配存储空间,也没有具体的值。形参仅仅是一个有具体的值。形参仅仅是一个“符号符号”。实际参数实际参数又称为实参,它是调用函数向被调用函数提又称为实参,它是调用函数向被调用函数提供的一些具体信息,可以是常量、变量或表达式,它供的一些具体信息,可以是常量、变量或表达式,它有具体的值。对于实参变量而言,它已经被分配了相有具体的值。对于实参变量而言,它已经被分配了相应的存储空间。应的存储空间。调用有参函数时,必须要提供与形参调用有参函数时,必须要提供与形参相匹配相匹配的实参。所谓的实参。所谓匹配是指实参与形参的个数相等,对应实参与形参的类型匹配是指实参与形参的个数相等,对应实参与形参的类型相同或赋值兼容。相同或赋值兼容。35C语言程序设计语言程序设计 温州理工学院温州理工学院 35参数传递参数传递(contd)在调用有参函数时,系统将会根据在调用有参函数时,系统将会根据形参的类型形参的类型为其分为其分配存储空间,而存储空间中的内容即配存储空间,而存储空间中的内容即形参的值形参的值,则来,则来自调用函数所提供的自调用函数所提供的实参实参。当被调用函数执行完毕返回调用函数时,当被调用函数执行完毕返回调用函数时,形参形参的存储的存储空间又被系统收回,空间又被系统收回,形参的值形参的值也就不复存在了。也就不复存在了。C语言中的参数传递通常是一种语言中的参数传递通常是一种单向的单向的“值传递值传递”。传递给被调用函数的参数值存放在临时变量中,而不是存传递给被调用函数的参数值存放在临时变量中,而不是存放在原来的变量中。放在原来的变量中。被调用函数不能直接修改主调函数中变量的值,而只能修被调用函数不能直接修改主调函数中变量的值,而只能修改其私有的临时副本的值。改其私有的临时副本的值。36C语言程序设计语言程序设计 温州理工学院温州理工学院 36函数调用与参数传递函数调用与参数传递(contd)#includevoid swap(int a,int b)/*定义子函数定义子函数*/int t;t=a;a=b;b=t;main()int x,y;x=10;y=20;printf(Before swapped:x=%d y=%dn,x,y);swap(x,y);/*调用函数调用函数*/printf(After swapped:x=%d y=%dn,x,y);getch();37C语言程序设计语言程序设计 温州理工学院温州理工学院 37函数调用与参数传递函数调用与参数传递(contd)调用调用函数函数:swap(x,y)被调用被调用函数函数:swap(int a,int b)实参实参形参形参 x y 10 20 a b x y 10 20 a b 10 20 x y 10 20 a b swap(x,y)swap(a,b)调用前调用前 调用时调用时 调用后调用后38C语言程序设计语言程序设计 温州理工学院温州理工学院 38函数调用的方式函数调用的方式函数表达式:函数表达式:函数作为表达式中的一项出现在表达式中,以函数返函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数是有返回回值参与表达式的运算。这种方式要求函数是有返回值的。值的。例如:例如:z=max(x,y)是一个赋值表达式,把是一个赋值表达式,把max的返回的返回值赋予变量值赋予变量z。函数语句:函数语句:函数调用的一般形式加上分号即构成函数语句。函数调用的一般形式加上分号即构成函数语句。例如:例如:printf(%d,a);scanf(%d,&b);都是以函数语句的方式调用函数。都是以函数语句的方式调用函数。39C语言程序设计语言程序设计 温州理工学院温州理工学院 39函数调用的方式函数调用的方式(contd)函数实参:函数实参:函数作为另一个函数调用的实际参数出现。这种情况函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的。函数必须是有返回值的。printf(“%d”,max(x,y);即是把即是把max 调用的返回值又作为调用的返回值又作为printf 函数的实参函数的实参来使用的。来使用的。在函数调用中还应该注意的一个问题是求值顺序在函数调用中还应该注意的一个问题是求值顺序的问题。所谓求值顺序是指对实参表中各量是自的问题。所谓求值顺序是指对实参表中各量是自左至右使用呢,还是自右至左使用。对此,各系左至右使用呢,还是自右至左使用。对此,各系统的规定不一定相同。统的规定不一定相同。40C语言程序设计语言程序设计 温州理工学院温州理工学院 40函数调用时,实参求值顺序的问题函数调用时,实参求值顺序的问题无论是从左至右求值,无论是从左至右求值,还是自右至左求值,其还是自右至左求值,其输出顺序都是不变的,输出顺序都是不变的,即输出顺序总是和实参即输出顺序总是和实参表中实参的顺序相同。如按照表中实参的顺序相同。如按照从右至左从右至左的顺序的顺序求值。运行结果应为:求值。运行结果应为:main()int i=8;printf(%dt%dt%dt%dn,+i,-i,i+,i-);printf(%d,i);41C语言程序设计语言程序设计 温州理工学院温州理工学院 41函数调用时,实参求值顺序的问题函数调用时,实参求值顺序的问题main()int i=8;printf(%dt%dt%dt%dn,+i,-i,i+,i-);printf(%d,i);输出值:输出值:8 输出后,输出后,i 取值为取值为7 输出值:输出值:7 输出后,输出后,i 取值为取值为8 输出值:输出值:7 输出后,输出后,i 取值为取值为7 输出值:输出值:8 输出后,输出后,i 取值为取值为842C语言程序设计语言程序设计 温州理工学院温州理工学院 42函数调用与参数传递函数调用与参数传递(contd)形式参数的设计形式参数的设计设计形式参数应从函数的功能分析入手,哪个设计形式参数应从函数的功能分析入手,哪个数据需要调用函数提供,这就应定义一个形式数据需要调用函数提供,这就应定义一个形式参数接收该数据。参数接收该数据。函数原型函数原型 在使用自定义函数时,除了进行函数的定义外,在使用自定义函数时,除了进行函数的定义外,还需要在调用该函数之前对其进行原型声明。还需要在调用该函数之前对其进行原型声明。函数原型声明的格式:函数原型声明的格式:类型符类型符 函数名函数名(形式参数形式参数);43C语言程序设计语言程序设计 温州理工学院温州理工学院 43函数调用与参数传递函数调用与参数传递(contd)函数原型使用说明:函数原型使用说明:函函数数原原型型声声明明语语句句最最后后的的分分号号不不能能省省略略,其其作作用用是是表表示示该该语语句句是是进进行行函函数数声声明明而而不不是是函函数数定定义。义。在原型声明中,形式参数名可以省略。在原型声明中,形式参数名可以省略。如如果果被被调调用用函函数数的的定定义义出出现现在在调调用用函函数数之之前前,可以不对被调用函数进行原型声明。可以不对被调用函数进行原型声明。如果被调用函数已在所有函数定义之前进行了如果被调用函数已在所有函数定义之前进行了原型声明,则在各个调用函数中不必再对该函原型声明,则在各个调用函数中不必再对该函数进行原型数进行原型声明。声明。44C语言程序设计语言程序设计 温州理工学院温州理工学院 44函数调用与参数传递函数调用与参数传递(contd)C语言语言中又规定在以下几种情况时可以省去主中又规定在以下几种情况时可以省去主调函数中对被调函数的函数说明调函数中对被调函数的函数说明:如果被调函数的返回值是整型或字符型时,可以不如果被调函数的返回值是整型或字符型时,可以不对被调函数作说明,而直接调用。这时系统将自动对被调函数作说明,而直接调用。这时系统将自动对被调函数返回值按整型处理。对被调函数返回值按整型处理。当被调函数的函数定义出现在主调函数之前时,在当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数再作说明而直接调主调函数中也可以不对被调函数再作说明而直接调用。用。对库函数的调用不需要再作说明,但必须把该函数对库函数的调用不需要再作说明,但必须把该函数的头文件用的头文件用include 命令包含在源文件前部。命令包含在源文件前部。45C语言程序设计语言程序设计 温州理工学院温州理工学院 45函数调用与参数传递函数调用与参数传递(contd)如在所有函数定义之前,在函数外预先说明了各个如在所有函数定义之前,在函数外预先说明了各个函数的类型,则在以后的各主调函数中,可不再对函数的类型,则在以后的各主调函数中,可不再对被调函数作说明。被调函数作说明。其中第一行对其中第一行对str 函数预先作了说明。因此在以后函数预先作了说明。因此在以后各函数中无须对各函数中无须对str 再作说明就可直接调用。再作说明就可直接调用。char str(int a);main()char str(int a)46C语言程序设计语言程序设计 温州理工学院温州理工学院 46函数调用与参数传递函数调用与参数传递(contd)函数原型声明和函数定义的区别函数原型声明和函数定义的区别函数原型声明的作用是将函数类型告诉编译系统,函数原型声明的作用是将函数类型告诉编译系统,使程序在编译阶段对调用函数的合法性进行全面的使程序在编译阶段对调用函数的合法性进行全面的检查,避免函数调用时出现参数个数或类型不一致检查,避免函数调用时出现参数个数或类型不一致等运行错误。等运行错误。函数定义部分则是函数的实际实现代码。函数定义部分则是函数的实际实现代码。char str(int a);main()char str(int a)47C语言程序设计语言程序设计 温州理工学院温州理工学院 47第八讲第八讲 函数函数概述概述函数的定义函数的定义函数调用与参数传递函数调用与参数传递函数的嵌套调用与递归调用函数的嵌套调用与递归调用数组作为函数参数数组作为函数参数局部变量与全局变量局部变量与全局变量变量的存储类别变量的存储类别内部函数与外部函数内部函数与外部函数程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间48C语言程序设计语言程序设计 温州理工学院温州理工学院 48函数的嵌套调用函数的嵌套调用void guess(int n)/*定义函数定义函数*/int n1,n2;for(n1=3;n1n/2;n1+=2)n2=n-n1;if(prime(n1)&prime(n2)printf(%d=%d+%dn,n,n1,n2);int prime(int n)/*定义函数定义函数*/int i,flag=1;for(i=2;i=6):);scanf(%d,&n);while(!(n=6&n%2=0);guess(n);/*调用函数调用函数*/getch();49C语言程序设计语言程序设计 温州理工学院温州理工学院 49函数的嵌套调用函数的嵌套调用50C语言程序设计语言程序设计 温州理工学院温州理工学院 50递归调用递归调用一个函数不仅可以调用其它函数,还可以直接或间接一个函数不仅可以调用其它函数,还可以直接或间接调用它本身,这种调用过程被称作调用它本身,这种调用过程被称作递归(递归(recursion)。例:用递归的方法计算例:用递归的方法计算n!。float fact(int n)float f;if(n0)printf(n%cn,x,z);else move(n-1,x,z,y);printf(%c-%cn,x,z);move(n-1,y,x,z);main()int h;printf(nInput the number of disks:);scanf(%d,&h);printf(the step to moving%2d diskes:n,h);move(h,a,b,c);56C语言程序设计语言程序设计 温州理工学院温州理工学院 56Hanoi(汉诺汉诺)塔问题塔问题递归函数递归函数move 有四个形参有四个形参n、x、y、z。n 表示圆盘数,表示圆盘数,x、y、z 分别表示三根针。分别表示三根针。move 函数的功能是把函数的功能是把x上的上的n 个圆盘移动到个圆盘移动到z 上。上。当当n=1 时,直接把时,直接把x上的圆上的圆盘移至盘移至z 上,输出上,输出xz。当当n!=1 则分为三步:则分为三步:递归调用递归调用move 函数,把函数,把n-1个圆