第五章 函 数. 第五章 函 数 教学目标 (1) 了解函数在程序设计中的作用; (2) 掌握函数的定义方法; (3) 掌握函数调用和参数传递的机制和方法; (4) 了解变量的作用域和生存期的概念。

Slides:



Advertisements
Similar presentations
因数与倍数 2 、 5 的倍数的特征
Advertisements

2.5 函数的微分 一、问题的提出 二、微分的定义 三、可微的条件 四、微分的几何意义 五、微分的求法 六、小结.
C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
第8章 函数 信息管理系.
Oracle数据库 Oracle 子程序.
6.4 字符串与指针 1. 用字符数组存放一个字符串.
第4章 数组 数组是由一定数目的同类元素顺序排列而成的结构类型数据 一个数组在内存占有一片连续的存储区域 数组名是存储空间的首地址
不确定度的传递与合成 间接测量结果不确定度的评估
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
第八章 函数 §8.1 概述 一个较大程序一般分为若干个程序模块,每一个模块实现一个特定的功能。所有的高级语言中都有子程序的概念,在C中子程序就是函数。 一个C程序可由一个主函数和若干个函数构成,由主函数调用其它函数,其它函数也可以相互调用.
C#程序设计基础 $5 流程控制.
資料大樓 --談指標與陣列 綠園.
函數(一) 自訂函數、遞迴函數 綠園.
EBNF 请用扩展的 BNF 描述 C语言里语句的结构; 请用扩展的 BNF 描述 C++语言里类声明的结构;
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C语言程序设计基础 刘新国.
第一章 程序的基本结构. 第一章 程序的基本结构 教材及授课结构 本章目标 基本内容 扩展阅读 上机指导 应用举例 习题.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第7章 函 数 本章要点: C语言程序结构和特点 函数的定义 函数的返回值与函数的类型 函数的调用及参数的传递关系 函数的嵌套与递归
Object-Oriented Programming in C++ 第一章 C++的初步知识
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
走进编程 程序的顺序结构(二).
辅导课程六.
计算机网络讲义 第5章 批量数据处理—数组 一维数组 排序和查找 二维数组 字符串.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
第五讲 四则运算计算器(一) 精品教程《C#程序设计与应用(第2版)清华大学出版社 谭恒松 主编
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
第五章 函数 5.1 函数的定义、调用与说明 5.2 函数间参数传递 5.3 递归函数 5.4 函数参数缺省 5.5 函数重载
C++语言程序设计 第二章 C++简单程序设计.
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
第七章 操作符重载 胡昊 南京大学计算机系软件所.
第一章 函数与极限.
六、函数 教学目标: 函数的概念、定义、调用和返回 带自定义函数的程序设计 递推算法 递归思想及算法实现 函数的参数传递方式 C语言程序设计.
C++大学基础教程 第3章 C++控制语句 北京科技大学 信息基础科学系.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
C语言程序设计 主讲教师:陆幼利.
程式結構&語法.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C++语言程序设计 第三章 函数.
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
目录 7.1 用户自定义函数的种类 7.2 函数的定义 7.3 被调函数的声明 7.4 函数的调用 7.5 函数的嵌套调用
物件導向程式設計 CH2.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第五章 函 数 要点:掌握函数的定义,函数的原形,函数的返回值,函数的调用,函数的形式参数和实际参数之间的关系;掌握函数重载的使用方法,关键字inline的含义与使用,掌握变量的作用域与生存期,了解函数的作用域。
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第4章 Excel电子表格制作软件 4.4 函数(一).
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
C++程式設計入門 變數與運算子 作者:黃建庭.
第九节 赋值运算符和赋值表达式.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
#include <iostream.h>
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
C++语言程序设计教程 第4章 函数 第4章 函数.
資料!你家住哪裏? --談指標 綠園.
计算机编程 信息管理与工程学院 2014年9月.
Presentation transcript:

第五章 函 数

教学目标 (1) 了解函数在程序设计中的作用; (2) 掌握函数的定义方法; (3) 掌握函数调用和参数传递的机制和方法; (4) 了解变量的作用域和生存期的概念。

基本内容 5.1概述 5.2 函数的定义和调用 5.3 函数间参数传递

5.1 概述 函数是构成程序的基本模块,每个函数完成一个计算或执行一个特定动作,具有相对独立的功能。 5.1 概述 函数是构成程序的基本模块,每个函数完成一个计算或执行一个特定动作,具有相对独立的功能。 通过函数,可以把一个复杂任务分解成为若干个易于解决的小任务。充分体现结构化程序设计由粗到精,逐步细化的设计思想。 C/C++提供三种类型的函数: 主函数main( ) 标准库函数 用户自定义函数

函数调用层次关系 main()函数是程序执行的入口,它可以调用其他函数。而其他一般函数既可以调用也可以被调用。 main ( ) fun2( ) fun1( ) fun3( ) fun1_1( ) fun2_1( ) fun2_2( ) main()函数是程序执行的入口,它可以调用其他函数。而其他一般函数既可以调用也可以被调用。

5.2 函数的定义和调用 5.2.1 函数的定义 5.2.2 函数的调用 5.2.3 函数声明

5.2.1 函数的定义 函数必须先定义,后使用。 定义函数的一般格式为: 函数体 函数类型 函数名(形式参数表) { 说明语句; 执行语句; 函数类型 函数名(形式参数表) { 说明语句; 执行语句; return 表达式; } 函数体

函数类型 函数类型:即调用该函数后所得到的函数值的类型,它由函数体内部的return语句提供。 如果某一函数确没有返回值,则使用说明符void。 例如:主函数的另一种形式 void main() { … … } 注意:这时函数中不能出现有返回值的return语句。

参数说明 形式参数表 (形参 )表示将从调用函数中接收哪些类型的数据 参数说明格式为: 变量类型 形参1,变量类型 形参2,…,变量类型 形参n 例: int array[], int count, doulbe distance

函数体 函数体本身是一个分程序,由语句和其他分程序组成。 语句分为说明语句和执行语句两类。 对某具体变量来说,应先说明,后使用。

5.2.2 函数的调用 函数要先定义,后调用。 调用函数时要考虑到函数本身的参数: 实参与形参必须一一对应: “虚实结合” 调用标准库函数时,要包含相应的头文件 输入/输出函数 iostream 字符串函数 cstring 常用数学函数 cmath 调用自定义函数时,要定义相应的实参,并给这些实参赋值。 函数名 ( 实参列表 ) 实参与形参必须一一对应: “虚实结合” “类型一致、位置一致、个数一致”

例5-1 求阶乘n! 算法分析: n!= n×(n-1)×…×3×2×1, 且0!=1 计算公式为: 函数的计算结果要返回主调函数,故设一个变量result n的阶乘结果可由一重循环来求得

#include <iostream> using namespace std; int fac(int n) { int result = 1; if(n == 0) return 1; while (n>1) result = result * n; n--; } return result; int main() { int m, r; cout << "请输入一个正整数,以计算其阶乘:"; cin >> m; r = fac(m) ; cout << m << "! = " << r << endl; return 0; main( )函数 调用 fac(3) 函数 fac(3) 主程序后续语句 return 6

函数间的信息交换 调用函数和被调用函数之间的信息交换是通过参数的结合和return语句来实现的。 数据流程是: 在调用函数中,先给实参赋值 通过函数调用,将数据从调用函数带到被调用函数 形参带值后,被调用函数即可进行相应的数据处理 如果有返回值,通过return语句带回到调用函数

5.2.3 函数声明 函数(原型)声明 函数声明的一般格式为: 将某函数的定义放在调用它的函数之后时,必须在被调用到之前对该函数先做说明 函数类型 函数名 ( 形式参数表 );

例 5-2:函数声明的使用——绝对值函数 运行结果: |m| = 5 #include <iostream> using namespace std; int abs(int x); // 函数声明 int main() // 主函数 { int m = -5; cout << "|m| = " << abs(m) << endl; return 0; } int abs(int x) // 函数定义 return x>=0?x:-x; // 使用问号表达式直接计算并返回结果 运行结果: |m| = 5

5.3 函数间的参数传递 形参:在参数表中声明的参数(变量)叫做函数的形式参数。 实参:在调用函数时,一般须为每一个形参给出其实际数据,即实际参数。 实参与形参有3种结合方式: 值调用、引用调用和地址调用。

值调用 值调用 优点: 缺点: 在调用时仅将实参的值赋给形参 在函数中对形参的任何修改不会影响到实参的值。 减少了调用函数与被调用函数之间的数据依赖,增强了函数自身的独立性。 缺点: 被调用函数向调用函数传递的数据仅有一个返回值,有时显得不够用。

Before exchange:a=1,b=2 After exchange:a=1,b=2 //例 5-3:交换两个变量的值(值调用) #include <iostream> using namespace std; void swap(int x, int y) { int tmp; tmp = x; x = y; y = tmp; } // 测试函数 swap() 用的主函数 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=2

5.4 变量的作用域和生存期 5.4.1 变量的作用域 5.4.2 变量的生存期

5.4.1 变量的作用域 根据作用域的不同,可将程序中的变量分为局部变量和全局变量 局部变量是在函数或分程序中说明的变量,只能在本函数或分程序的范围内使用。 全局变量说明于所有函数之外,可以为本源程序文件中位于该全局变量说明之后的所有函数共同使用。 全局变量可以在各个函数之间建立数据传输通道,但滥用会破坏程序的模块化结构。 如出现同名变量,遵循“地方保护主义”原则。

#include <iostream> using namespace std; int x; // 声明全局变量 int f1() // 在函数f1()使用全局变量x { return (x+5)*(x+5); } int f2(int y) int x =y+5; // 函数f2()中声明了一个名为x的局部变量 return x*x; int main() { x = 3; // 在主函数中为全局变量x赋值 cout<<"调用函数f1()的结果:"<<f1()<<endl; cout<<"调用函数f2()的结果:"<<f2(2)<<endl; cout<<"x = "<<x<<endl; return 0; 运行结果: 调用函数f1()的结果:64 调用函数f2()的结果:49 x = 3

5.4.2 变量的生存期 根据生存期的不同,可将程序中的变量分为自动变量和静态变量 自动变量(auto)的生存期是说明了自动变量的函数或分程序。它对存储空间的利用是动态的。其初值在每次为自动变量分配存储后都要重新设置。 静态变量(static)的生存期就是整个程序的运行期。在程序开始运行前就为其分配相应的存储空间,在程序的整个运行期间一直占用,直到结束。

例5-5:自动变量的使用 #include <iostream> using namespace std; int func() { int count = 0; // 定义自动局部变量并初始化 count++; return count; } int main() { // 分别调用10次func( ) 函数 for(int i=0; i<10; i++) cout<<func()<<"\t"; cout<<endl; return 0; 运行结果: 1 1 1 1 1 1 1 1 1 1

例5-6:静态局部变量的使用 #include <iostream> using namespace std; int func() { static int count = 0; // 声明静态局部变量并初始化 count++; return count; // 本函数每执行一次,变量值加1 } int main() { // 分别调用10次func( ) 函数 for(int i=0;i<10;i++) cout<<func()<<"\t"; cout<<endl; return 0; 运行结果: 1 2 3 4 5 6 7 8 9 10

扩展阅读 5.5 函数的嵌套和递归调用 5.6带默认形参值的函数 5.7函数重载 5.8函数模板

5.5 函数的嵌套和递归调用 5.5.1 函数的嵌套 5.5.2 递归调用

5.5.1 函数的嵌套

例5-7 求两个整数的最小公倍数 算法分析 两个正整数的最小公倍数可以由下面公式计算出来: 两个正整数的最小公倍数=两数乘积÷两数的最大公约数 求最大公约数的辗转相除法: 步骤1: 如果p < q,交换p 和q; 步骤2: 求p/q的余数r; 步骤3: 如果r ==0,则 q 就是所求的结果; 否则,反复做如下工作:令p = q,q = r,重新计算 p 和q 的余数r,直到r ==0为止,则 q 就是原来的两正整数的最大公约数。

#include <iostream> using namespace std; int gcd(int p, int q) //求最大公约数 { int r; if(p<q) { r = p; p = q; q = r;} r = p%q; while(r != 0) { p = q; q = r; r = p%q; } return q; int lcm(int p, int q) //求最小公倍数 { return p*q/gcd(p, q); int main() { int p, q; cout<< "请输入两个整数:" ; cin >> p >> q; cout << "两个整数的最小公倍数是:" << lcm(p, q) << endl; return 0;

5.5.2 递归调用 当定义一个函数时,如果其函数体内有调用其自身的语句,则该函数称为递归函数。 一个直接或间接地调用了自身的算法就是递归算法。

例5-8 采用递归算法求n! 算法: 由阶乘的概念可以写出其递归定义: 0! = 1 n! = n*(n-1)!

#include <iostream> using namespace std; int fac(int n) // 函数fac():求阶乘的递归函数 { if(n==0) // 0!=1 return 1; else return n*fac(n-1); // n!=n*(n-1)! } int main() int n; cout << "请输入一个整数n,以计算n!:"; cin >> n; cout << n << "! = " << fac(n) << endl; return 0;

递归函数的调用顺序 当n取5时,产生下列调用序列: 回代结果: fac(5)= 5 *fac(4) fac(5)=5*4*3*2*1

递归基本定理 一个问题是否可以转换为递归来处理必须满足以下条件: (1) 必须包含一种或多种非递归的基本形式; (1) 必须包含一种或多种非递归的基本形式; (2) 一般形式必须能最终转换到基本形式; (3) 由基本形式来结束递归。

5.6 带默认形参值的函数 在函数定义时,可在形参列表中预先给一些默认值。 当调用这种函数时,若为相应参数给出实参,则用实参初始化对应形参;如果没给出,则自动采用预先给定的默认形参值。 注意: 要保证所有的缺省参数均放在参数表的最后,即默认参数值必须按从右向左的顺序声明。如: void func(int x, int n1 = 1, int n2 = 2);

例 5-9:带默认形参值的函数 #include <iostream> using namespace std; void func(int x = 1, int y = 2, int z = 3) // 带默认形参值的函数 { cout << "参数x:"<<x<<endl; cout << "参数y:"<<y<<endl; cout << "参数z:"<<z<<endl; } int main() { cout << "未给出实参值的情况:"<<endl; func(); cout << "给出1个实参值的情况:"<<endl; func(10); cout << "给出2个实参值的情况:"<<endl; func(20, 30); cout << "给出3个实参值的情况:"<<endl; func(20, 30, 40); return 0;

5.7函数重载 函数重载: 注意: 一组参数和返回值不同的函数共用一个函数名。 重载函数之间必须在参数的类型或个数方面有所不同。只有返回值类型不同的几个函数不能重载。

#include <iostream> using namespace std; int max(int x, int y) //求两个整型数的最大值 { return (x>y)?x:y; } double max(double x, double y) //求两个双精度数的最大值 char max(char x, char y) //求两个字符的最大值 int main() { int m1=5, m2=3; double d1=12.5, d2=6.4; char c1='a', c2='b'; cout<<m1<<"和"<<m2<<"中的最大值是: "<<max(m1, m2)<< endl; cout<<d1<<"和"<<d2<<"中的最大值是: "<<max(d1, d2)<< endl; cout<<c1<<"和"<<c2<<"中的最大值是: "<<max(c1, c2)<< endl; return 0;

5.8 函数模板 函数模板用于定义一个抽象通用的函数,从而能够对不同类型的数据进行相同的处理。 定义一个函数模板的格式为: template < typename 类型参数> 函数类型 函数名 ( 形式参数表 ) { 函数体 }

例 5-11:求最大值的函数模板 #include <iostream> using namespace std; template <typename T> T tmax(T a, T b) //求两个数据最大值的函数模板 { return a>b?a:b; } int main() { int m1=5, m2=3; double d1=12.5, d2=6.4; char c1='a', c2='b'; cout<<m1<<"和"<<m2<<"中的最大值是: "<<tmax(m1, m2)<< endl; cout<<d1<<"和"<<d2<<"中的最大值是: "<<tmax(d1, d2)<< endl; cout<<c1<<"和"<<c2<<"中的最大值是: "<<tmax(c1, c2)<< endl; return 0;

上机指导 5. 9 Visual C++的跟踪调试功能

Debug工具栏 (1)Restart(快捷键:Ctrl+Shift+F5) (2)Stop Debugging(快捷键:Shift+F5) (3)Break Execution: (4)Apply Code Changes(快捷键:Alt+F10) (5)Show Next Statement(快捷键:Alt+Num *) (6)Step Into(快捷键:F11) (7)Step Over(快捷键F10) (8)Step Out(快捷键:Shift+F11) (9)Run To Cursor(快捷键:Ctrl+F10)

应用举例 例5-12 显示出杨辉三角形的前10行 算法讨论: 杨辉三角形的每一项也可以用二项式 的展开式的系数来表示。 杨辉三角形的通项公式 例5-12 显示出杨辉三角形的前10行 算法讨论: 杨辉三角形的每一项也可以用二项式 的展开式的系数来表示。 杨辉三角形的通项公式 求解杨辉三角形的步骤为: 编写出阶乘函数 在主函数中调用阶乘函数来构造杨辉三角形的通项公式,循环显示输出

#include <iostream> #include <cmath> using namespace std; int fac(int n) //求n!的函数 { int result=1; while(n>1) result =result*n; n=n-1; } return result; int main() for(int n=0; n<10; n=n+1) for(int m=0; m<=n; m=m+1) cout<<fac(n)/(fac(m)*fac(n-m))<<"\t"; cout<<endl; return 0;

例 5-13:找出100-200之间的所有素数 #include <iostream> using namespace std; bool isprime(int a) { for(int i=2; i<=a/2; i++) if(a%i == 0) return false; } return true; int main() for(int m=100; m<=200; m++) if(isprime(m)) cout<<m<<'\t'; return 0;

例 5-14 根据用户输入的宽和高的数目,显示一个由“*”号组成的矩形 #include <iostream> using namespace std; void rectangle(int w,int h) { int i, j; for(j=0; j<w; j++) cout<<"*"; // 显示矩形上面的边 cout<<endl; for(i=1; i<h-1; i++) // 显示矩形侧边 cout<<"*"; for(j=1; j<w-1; j++) cout<<" "; cout<<"*"<<endl; } for(j=0; j<w; j++) cout<<"*"; // 显示矩形下面的边 int main() int w, h; cout<<"请输入矩形的宽和高(要求为正整数值,中间使用空格隔开):"; cin>>w>>h; rectangle(w, h); return 0;

例 5-15:当用户输入一个整数和数字后,能够统计出该整数中包含这一数字的个数 #include <iostream> using namespace std; int count(int m,int n) { int sum=0; m = m>0?m:-m; // 若m为负整数,则转换为正整数形式 do if(m%10 == n)sum++; m = m/10; }while(m!=0); // 将整数逐位分解判断 return sum; } int main() int m,n; cout<<"请输入一个整数和一个数字:"; cin>>m>>n; cout<<"整数"<<m<<"中数字"<<n<<"的个数是"<<count(m, n)<<endl; return 0;

案例:金字塔图形 编写一个函数: void draw(int n) 可根据整数 n (0<n<14) ,输出由字母组成的金字塔图形。 请输入n值:6 A ABC ABCDE ABCDEFG ABCDEFGHI ABCDEFGHIJK 教学设问 1. 为什么n的值要小于14呢? 2. 无返回值函数如何调用? *更多案例见本书配套教材《C/C++语言程序设计案例教程 》罗建军等编著,清华大学出版社

问题分析 金字塔图形有以下特点: 输入的n表示要输出n行 每行都是从A开始,按字母顺序输出

//金字塔图形 #include <iostream> using namespace std; void draw(int n) { int i,j,m=0; char c; for(i=1;i<=n;i++) for(j=1;j<=n+1-i;j++) cout<<" "; for(c='A';c<='A'+m;c++) cout<<c; m=m+2; cout<<endl; } int main() int n; cout<<"请输入n的值:"; cin>>n; draw(n); return 0;

进一步思考 如果输出的金字塔图形都是由小写字母组成,如何修改程序? 如果只想输出金字塔图形的左半边,如何修改程序?

结 束 语 学好程序设计语言的唯一途径是 你的编程能力与你在计算机上投入的时间成 上机练习 正比