《大学c程序设计教程.ppt》由会员分享,可在线阅读,更多相关《大学c程序设计教程.ppt(48页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、大学大学C+程序设计教程程序设计教程西安交通大学西安交通大学计算机教学实验中心计算机教学实验中心http:/第第6章章 函数函数u本章目标:本章目标:掌握掌握C+程序中函数的定义方法和函数调程序中函数的定义方法和函数调用规则。用规则。掌握掌握C+程序中主调函数和被调函数之间程序中主调函数和被调函数之间进行数据传递的规则进行数据传递的规则掌握函数的返回值和它的类型。掌握函数的返回值和它的类型。掌握内联函数的概念掌握内联函数的概念 掌握函数重载的概念掌握函数重载的概念1授课内容u6.1 6.1 函数概述函数概述u6.2 6.2 函数的定义函数的定义u6.3 6.3 函数的调用函数的调用u6.4 6
2、.4 函数原型函数原型u6.5 6.5 函数间的参数传递函数间的参数传递u6.6 6.6 局部变量和全局变量局部变量和全局变量u6.7 6.7 带有缺省参数的函数带有缺省参数的函数u调试技术调试技术u程序设计举例程序设计举例26.1 函数概述函数概述uC+语言程序的结构特点是,程序整语言程序的结构特点是,程序整体由一个或多个称为函数的程序块组体由一个或多个称为函数的程序块组成。每个函数都具有各自独立的功能成。每个函数都具有各自独立的功能和明显的界面,从而使程序具有清晰和明显的界面,从而使程序具有清晰的模块结构。的模块结构。3u在在C+语言程序中的若干个函数中必须有一语言程序中的若干个函数中必须
3、有一个且只能有一个函数成为主函数。程序的执个且只能有一个函数成为主函数。程序的执行总是从主函数开始,主程序的语句执行完,行总是从主函数开始,主程序的语句执行完,则程序执行结束。则程序执行结束。u在一个函数中可以使用另一个函数的功能,在一个函数中可以使用另一个函数的功能,这成为函数调用。这成为函数调用。C+提供三种类型的函数:提供三种类型的函数:main主函数主函数标准库函数标准库函数用户自定义函数用户自定义函数4说明:说明:u(1)一个源程序文件由一个或多个函数一个源程序文件由一个或多个函数组成。组成。u(2)一个程序由一个或多个源程序文一个程序由一个或多个源程序文件组成。件组成。u(3)程序
4、的执行从程序的执行从main函数开始,函数开始,调用其他函数后流程回到调用其他函数后流程回到main函数,函数,在在main函数中结束整个程序的运行。函数中结束整个程序的运行。5u(4)所有函数都是平行的,即在定义函数时所有函数都是平行的,即在定义函数时是互相独立的,一个函数并不从属于另一函是互相独立的,一个函数并不从属于另一函数,即函数不能嵌套定义,函数间可以互相数,即函数不能嵌套定义,函数间可以互相调用,但不能调用调用,但不能调用main函数。函数。u(5)从用户使用的角度看,函数有两种:从用户使用的角度看,函数有两种:标准函数;标准函数;用户自己定义的函数用户自己定义的函数u(6)从函数
5、的形式看,函数分两类:从函数的形式看,函数分两类:无参函数;无参函数;有参函数有参函数66.2 函数定义函数定义u函数的定义就是编写完成函数功能的函数的定义就是编写完成函数功能的程序块。程序块。u函数定义的一般格式:函数定义的一般格式:()7函数值类型函数值类型uC+语言函数返回值所具有的数据类语言函数返回值所具有的数据类型与变量类型相同。当函数返回值是型与变量类型相同。当函数返回值是数值时,它可以是带符号或数值时,它可以是带符号或unsigned的的char、int、short、long型以及型以及float、double型。当返回值是地址时,函数型。当返回值是地址时,函数的数据类型是指针型
6、。当函数没有返的数据类型是指针型。当函数没有返回值时,它的类型是回值时,它的类型是void。8形式参数形式参数u1函数可以带有零个或多个形式参数。函数可以带有零个或多个形式参数。u2函数的是函数的内部变量。即形式函数的是函数的内部变量。即形式参数的生存期和作用域仅限于函数内参数的生存期和作用域仅限于函数内部。部。u3形式参数只是被初始化的内部变量,形式参数只是被初始化的内部变量,即只有当函数被调用,形式参数才被即只有当函数被调用,形式参数才被赋予调用函数传递来的实参数值赋予调用函数传递来的实参数值92函数值类型声明函数值类型声明u说明调用该函数后所得到的函数值类型,是说明调用该函数后所得到的函
7、数值类型,是通过函数体内部的通过函数体内部的return语句提供。语句提供。ureturn语句提供的表达式的值的类型应与函语句提供的表达式的值的类型应与函数说明中的函数值类型一致。数说明中的函数值类型一致。u如果某一函数确实没有返回值,则使用说明如果某一函数确实没有返回值,则使用说明符符void。例如:。例如:void main()u这时函数中不能出现有返回值的这时函数中不能出现有返回值的return语句。语句。103形式参数声明形式参数声明 u表示将从主调函数中接收哪些类型的信息表示将从主调函数中接收哪些类型的信息u例:例:double grav(double m1,double m2,do
8、uble distance)u形式参数可以在函数体中引用,可以输入、形式参数可以在函数体中引用,可以输入、输出、赋值或参与运算输出、赋值或参与运算 u参数说明格式为:参数说明格式为:,u例:例:int array,int count114.函数间的信息交换函数间的信息交换uC+语言中可以使用参数在函数之间传递数语言中可以使用参数在函数之间传递数据。据。u主函数和子函数之间的信息交换是通过参数主函数和子函数之间的信息交换是通过参数的结合和的结合和return语句来实现的。语句来实现的。u数据流程是:数据流程是:在主程序中,先给实参赋值在主程序中,先给实参赋值通过函数调用,将数据从主函数带到子函数
9、通过函数调用,将数据从主函数带到子函数形参带值后,即可进行相应的数据处理形参带值后,即可进行相应的数据处理如果有结果值,通过如果有结果值,通过return语句带回到主函数语句带回到主函数12u参数传递可以分为:参数传递可以分为:u1数据复制方式数据复制方式u2地址传递方式地址传递方式u3利用参数返回结果利用参数返回结果u4利用返回值传递数据利用返回值传递数据u5使用全局变量传递数据使用全局变量传递数据13例例6.1 6.1 求求N N的阶乘的阶乘n n!u算法分析:算法分析:计算公式为:计算公式为:n!=n(n-1)321,且且0!=1在子函数中只需一个数据在子函数中只需一个数据x,故设一个参
10、数,故设一个参数n计算结果要返回主函数,故设一个变量计算结果要返回主函数,故设一个变量resultn的阶乘可在一重循环中实现的阶乘可在一重循环中实现因阶乘的结果值很大,故设结果变量为长整数因阶乘的结果值很大,故设结果变量为长整数14例例6.1 求求N的阶乘的阶乘n!(续)!(续)uint fac(int n)uint result=1;uif(n1)uresult*=n;un-;uureturn result;u156.2 函数的调用函数的调用u在在C+中,除了主函数外,其他任何函数都中,除了主函数外,其他任何函数都不能单独作为程序运行。任何函数功能的实不能单独作为程序运行。任何函数功能的实现
11、都是通过被主函数直接或间接调用进行的。现都是通过被主函数直接或间接调用进行的。所谓函数调用,就是使程序转去执行函数体。所谓函数调用,就是使程序转去执行函数体。u无参函数的调用格式为:无参函数的调用格式为:函数名函数名()u有参函数的调用格式为:有参函数的调用格式为:函数名函数名(实参表实参表)u其中实际参数简称实参,用来将实际参数的其中实际参数简称实参,用来将实际参数的值传递给形参,因此可以是常量、具有值的值传递给形参,因此可以是常量、具有值的变量或表达式。变量或表达式。166.3 函数的调用(续)函数的调用(续)u调用函数时要考虑到函数本身的参数;调用函数时要考虑到函数本身的参数;调用标准库
12、函数时,要包含相应的头文件调用标准库函数时,要包含相应的头文件输入/输出函数 stdio.h字符串函数 string.h常用数学函数 math.h调用自定义函数时,要定义相应的实参,并给调用自定义函数时,要定义相应的实参,并给这些实参赋值。这些实参赋值。u实参与形参必须一一对应实参与形参必须一一对应:“类型一致、位置一致、个数一致类型一致、位置一致、个数一致”17例例62 求求N的阶乘的阶乘n!#includeint fac(int n)void main()int n;coutn;coutn!=fac(n)endl;18图图6.1 函数调用和返回的过程函数调用和返回的过程196.4 函数原型
13、函数原型u函数和变量一样,在使用之前要先说函数和变量一样,在使用之前要先说明。明。u函数原型可省略的情况函数原型可省略的情况:“先定义,先定义,后引用后引用”u函数原型的一般形式:函数原型的一般形式:();206.4 函数间的参数传递函数间的参数传递u(1)在定义函数中指定的形参,在未出现函在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。数调用时,它们并不占内存中的存储单元。u(2)实参可以是常量、变量或表达式,如:实参可以是常量、变量或表达式,如:fac(3a);u(3)在被定义的函数中,必须指定形参的类在被定义的函数中,必须指定形参的类型型u(4)实参与形参的类型应
14、相同或赋值兼容。实参与形参的类型应相同或赋值兼容。u(5)C+有三种调用方式:传值调用、引用有三种调用方式:传值调用、引用调用和地址调用调用和地址调用。21值调用值调用u值传递值传递在调用时仅将实参的值赋给形参,在函数中对在调用时仅将实参的值赋给形参,在函数中对形参值的任何修改都不会影响到实参的值。形参值的任何修改都不会影响到实参的值。u好处:好处:减少了调用函数与被调用函数之间的数据依赖,减少了调用函数与被调用函数之间的数据依赖,增强了函数自身的独立性。增强了函数自身的独立性。u缺点:缺点:被调用函数向调用函数传递的数据仅有一个返被调用函数向调用函数传递的数据仅有一个返回值,有时显得不够用回
15、值,有时显得不够用22236-4:交换两个变量的值:交换两个变量的值#include void swap(int x,int y)int tmp;tmp=x;x=y;y=tmp;int main()int a=1,b=2;cout Before exchange:a=a ,b=b endl;swap(a,b);cout After exchange:a=a ,b=b endl;return 0;输出输出 Before exchange:a=1,b=2 After exchange:a=1,b=224引用调用引用调用 u由于被调用函数向调用函数传递的数据仅有由于被调用函数向调用函数传递的数据仅有
16、一个返回值,有时显得不够用。一个返回值,有时显得不够用。u引用是一种特殊类型的变量,可以被认为是引用是一种特殊类型的变量,可以被认为是另一个变量的别名。另一个变量的别名。u通过引用名与通过被引用的变量名访问变量通过引用名与通过被引用的变量名访问变量的效果是一样的。的效果是一样的。u引用运算符引用运算符“&”用来说明一个引用。例如用来说明一个引用。例如uint i,&refi=i;25#include void swap(int&x,int&y)int tmp=x;x =y;y =tmp;int main()int a=1,b=2;cout Before exchange:a=a ,b=b en
17、dl;swap(a,b);cout After exchange:a=a ,b=b endl;return 0;/6-5:交换两个整形变量的值:交换两个整形变量的值266.5 局部变量和全局变量局部变量和全局变量 u根据作用域的不同,可将程序中的变根据作用域的不同,可将程序中的变量分为量分为u局部变量和全局变量局部变量和全局变量u根据生存期的不同,可将程序中的变根据生存期的不同,可将程序中的变量分为量分为u静态变量和自动变量静态变量和自动变量27变量的存储机制与变量的存储机制与C+C+的内存布的内存布局局 操操作作系系统统为为一一个个C+C+程程序序的的运运行行所所分分配配的的内内存分为四个区
18、域,存分为四个区域,程序在内存中的区域程序在内存中的区域所示:所示:用户区用户区堆区堆区(动态数据动态数据)全局数据区全局数据区(全局、静态变全局、静态变量量)栈区(函数局部数据)栈区(函数局部数据)代码区(程序代码)代码区(程序代码)28局部变量局部变量u定义在函数内或块内的变量称为局部定义在函数内或块内的变量称为局部变量。变量。u局部变量在程序运行到它所在的块时局部变量在程序运行到它所在的块时建立在栈中,该块执行完毕局部变量建立在栈中,该块执行完毕局部变量占有的空间即被释放。占有的空间即被释放。u局部变量在定义时可加修饰词局部变量在定义时可加修饰词auto,但通常省略。局部变量在定义时若未
19、但通常省略。局部变量在定义时若未初始化,其值为随机数。初始化,其值为随机数。29全局变量全局变量u全局变量说明于所有函数之外,可以全局变量说明于所有函数之外,可以为本源程序文件中位于该全局变量说为本源程序文件中位于该全局变量说明之后的所有函数共同使用。明之后的所有函数共同使用。u全局变量可以在各个函数之间建立数全局变量可以在各个函数之间建立数据传输通道,但滥用会破坏程序的模据传输通道,但滥用会破坏程序的模块化结构。块化结构。u如出现同名变量,遵循如出现同名变量,遵循“地方保护主地方保护主义义”原则。原则。30举例举例:局部变量和全局变量局部变量和全局变量int x;/说明全局变量说明全局变量i
20、nt func1(int x)/函数函数func1()有一个名为有一个名为x的的参数参数 y=x;.int func2(int y)/函数函数func2()中说明了一个名中说明了一个名为为x的局部变量的局部变量 int x;.void main()/在主函数中为全局变量在主函数中为全局变量x赋值赋值.x=0;.31自学内容u6.6 带有缺省参数的函数带有缺省参数的函数u6.7 C+的库函数的库函数u6.8 变量的存储类别变量的存储类别326.6 带有缺省参数的函数带有缺省参数的函数 double func(double x,double y,int n=1000);则其参数则其参数n带有缺省参
21、数值带有缺省参数值u调用方式:调用方式:a=func(b,c);a=func(b,c,2000);336.7 C+的库函数的库函数#include#include#include#include#include#include#include 346.9 变量的存储类别变量的存储类别 u存储类型决定了变量的生命期,变量生命期存储类型决定了变量的生命期,变量生命期指从获得空间到空间释放之间的时期。指从获得空间到空间释放之间的时期。u存储类型的说明符有四个存储类型的说明符有四个:auto,register,static和和extern。前两者称为自动类型,后两。前两者称为自动类型,后两者分别为静态
22、和外部类型。者分别为静态和外部类型。uauto:前面提到的局部变量都是自动类型。:前面提到的局部变量都是自动类型。其空间分配于块始,空间释放于块终,且由其空间分配于块始,空间释放于块终,且由系统自动进行。自动变量保存在栈中,且是系统自动进行。自动变量保存在栈中,且是在程序运行过程中获得和释放空间,未初始在程序运行过程中获得和释放空间,未初始化时值为随机数。化时值为随机数。35uregister:为提高程序运行效率,可以将某些为提高程序运行效率,可以将某些变量保存在寄存器中,即说明为寄存器变量,变量保存在寄存器中,即说明为寄存器变量,但不提倡使用。但不提倡使用。ustatic:静态变量。根据被修
23、饰变量的位置:静态变量。根据被修饰变量的位置不同,分为局部(内部)静态变量和全局不同,分为局部(内部)静态变量和全局(外部)静态变量。所有静态变量均存放在(外部)静态变量。所有静态变量均存放在全局数据区,编译时获得存储空间,未初始全局数据区,编译时获得存储空间,未初始化时自动全化时自动全0,且只初始化一次。,且只初始化一次。36自动变量和静态变量自动变量和静态变量u静态变量的生存期就是整个程序的运静态变量的生存期就是整个程序的运行期。在程序开始运行前就为其分配行期。在程序开始运行前就为其分配相应的存储空间,在程序的整个运行相应的存储空间,在程序的整个运行期间一直占用,直到结束。期间一直占用,直
24、到结束。u自动变量的生存期是说明了自动变量自动变量的生存期是说明了自动变量的函数或分程序。它对存储空间的利的函数或分程序。它对存储空间的利用是动态的。其初值在每次为自动变用是动态的。其初值在每次为自动变量分配存储后都要重新设置。量分配存储后都要重新设置。37/6-6:静态局部变量的使用:静态局部变量的使用#include int func()static int count=0;return+count;int main()for(int i=0;i10;i+)coutfunc()t;coutendl;return 0;38变量的生存期与作用域变量的生存期与作用域局部变量局部变量全局变量全局变
25、量自动变量自动变量int x;int x;静态变量静态变量static static int x;int x;局部静态变量局部静态变量int xint x;全局静态变量全局静态变量39Developer Studio的跟踪调试功能 uStep Into(快捷键:(快捷键:F11):跟踪):跟踪uStep Over(快捷键(快捷键F10):单步执行):单步执行uStep Out(快捷键:(快捷键:Shift+F11):从函数体):从函数体内运行到外内运行到外uRun To Cursor(快捷键:(快捷键:Ctrl+F10):从当):从当前位置运行到编辑光标前位置运行到编辑光标u观察窗口(观察窗口
26、(Watch)用于观察指定变量或表)用于观察指定变量或表达式的值达式的值u变量窗口(变量窗口(Variables)用于观察断点处或其)用于观察断点处或其附近的变量的当前值。附近的变量的当前值。u调用栈窗口(调用栈窗口(Call Stack)用于观察调用栈中)用于观察调用栈中还未返回的被调用函数列表。还未返回的被调用函数列表。40调试技术:续续Developer Studio的Debug工具栏41程序举例程序举例u例例6-7 打印打印100010000之间的回文数。所谓之间的回文数。所谓回文数是指其各位数字左右对称的整数,例回文数是指其各位数字左右对称的整数,例如如12321、789987、1等
27、都是十进制回文数。等都是十进制回文数。u例例6-8 编写一个用于字符串比较的函数编写一个用于字符串比较的函数mystrcmp()。u例例6-9 利用高斯消去法解利用高斯消去法解n元一次方程组。元一次方程组。u例例6-10 定义一个结构体矩形定义一个结构体矩形Rectangle,根,根据给出矩形的左上角顶点坐标和一个右下角据给出矩形的左上角顶点坐标和一个右下角顶点坐标,计算该矩形的面积。顶点坐标,计算该矩形的面积。42例例6-8 编写一个用于字符串比较的函数编写一个用于字符串比较的函数mystrcmp()。u分析分析:u 设计了一个循环,从两个字符串的第一个字设计了一个循环,从两个字符串的第一个
28、字符开始比较,直到出现不同的字符,或者有一符开始比较,直到出现不同的字符,或者有一个字符串已经结束为止。从程序中可以看出,个字符串已经结束为止。从程序中可以看出,这时如果两个字符串相等,则函数这时如果两个字符串相等,则函数mystrcmp()返回返回0;如果字符串;如果字符串s1大于字符串大于字符串s2,则返回一,则返回一个正数个正数;如果字符串如果字符串s1小于字符串小于字符串s2,则函数返,则函数返回一个负数。回一个负数。43例例6-8 编写一个用于字符串比较编写一个用于字符串比较的函数的函数mystrcmp()。u/Example 6-11:比较两个字符串:比较两个字符串u#includ
29、e uint mystrcmp(char s1,char s2)uint i=0;uwhile(s1i=s2i&s1i!=0&s2i!=0)ui+;ureturn s1i-s2i;u44例例6-10 定义一个结构体矩形定义一个结构体矩形Rectangle,根据给出矩,根据给出矩形的左上角顶点坐标和一个右下角顶点坐标,形的左上角顶点坐标和一个右下角顶点坐标,计算该矩形的面积。计算该矩形的面积。45/Example 6-10:计算矩形的面积计算矩形的面积#include#include struct Rectangleint topleft_x;int topleft_y;int bottomri
30、ght_x;int bottomright_y;46上机练习题上机练习题1.1.编写字符串查找编写字符串查找mystrchr()mystrchr()。2.2.编写字符串反转函数编写字符串反转函数mystrrev()mystrrev()。3.3.求数组中最大、最小元素的函数。求数组中最大、最小元素的函数。4.4.使用递归算法编写求斐波那契数列的第使用递归算法编写求斐波那契数列的第n n项项FEB(n)FEB(n)的函数。的函数。5.5.编写函数编写函数isprime(int a)isprime(int a)用来判断变量用来判断变量a a是是否为素数否为素数,若是素数若是素数,函数返回函数返回1 1,否则返回,否则返回0 0。调用该函数找出任意给定的调用该函数找出任意给定的n n个整数中的素数。个整数中的素数。47