《C++程序设计》 主讲教师:张玉宏.

Slides:



Advertisements
Similar presentations
2.8 函数的微分 1 微分的定义 2 微分的几何意义 3 微分公式与微分运算法则 4 微分在近似计算中的应用.
Advertisements

C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
第8章 函数 信息管理系.
第五章 二次型. 第五章 二次型 知识点1---二次型及其矩阵表示 二次型的基本概念 1. 线性变换与合同矩阵 2.
第 2 章 初探 C++.
第一章 C语言概述 计算机公共教学部.
Oracle数据库 Oracle 子程序.
一、原函数与不定积分 二、不定积分的几何意义 三、基本积分公式及积分法则 四、牛顿—莱布尼兹公式 五、小结
不确定度的传递与合成 间接测量结果不确定度的评估
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
在PHP和MYSQL中实现完美的中文显示
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
第八章 函数 §8.1 概述 一个较大程序一般分为若干个程序模块,每一个模块实现一个特定的功能。所有的高级语言中都有子程序的概念,在C中子程序就是函数。 一个C程序可由一个主函数和若干个函数构成,由主函数调用其它函数,其它函数也可以相互调用.
函數(一) 自訂函數、遞迴函數 綠園.
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C语言程序设计基础 刘新国.
第7章 函 数 本章要点: C语言程序结构和特点 函数的定义 函数的返回值与函数的类型 函数的调用及参数的传递关系 函数的嵌套与递归
Object-Oriented Programming in C++ 第一章 C++的初步知识
第 6 章 函式.
管理信息结构SMI.
走进编程 程序的顺序结构(二).
辅导课程六.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
§2 求导法则 2.1 求导数的四则运算法则 下面分三部分加以证明, 并同时给出相应的推论和例题 .
第二章 Java语言基础.
第七章 函数 西安工程大学.
第一章 函数与极限.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
数列.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
C语言程序设计 主讲教师:陆幼利.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
Chapter 2 & Chapter 3.
$9 泛型基础.
THE C PROGRAMMING LANGUAGE
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
第7章 函 数 7.1 函数的定义与调用 7.2 函数的嵌套调用与递归调用 7.3 数组作为函数参数 7.4 内部变量与外部变量
C语言程序设计.
Oop8 function函式.
目录 7.1 用户自定义函数的种类 7.2 函数的定义 7.3 被调函数的声明 7.4 函数的调用 7.5 函数的嵌套调用
物件導向程式設計 CH2.
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
第五章 函 数 要点:掌握函数的定义,函数的原形,函数的返回值,函数的调用,函数的形式参数和实际参数之间的关系;掌握函数重载的使用方法,关键字inline的含义与使用,掌握变量的作用域与生存期,了解函数的作用域。
信号量(Semaphore).
第5章 函 数.
第4章 Excel电子表格制作软件 4.4 函数(一).
第九节 赋值运算符和赋值表达式.
3.16 枚举算法及其程序实现 ——数组的作用.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
挑戰C++程式語言 ──第9章 函數.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二节 函数的极限 一、函数极限的定义 二、函数极限的性质 三、小结 思考题.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
C++语言程序设计教程 第4章 函数 第4章 函数.
第十七讲 密码执行(1).
資料!你家住哪裏? --談指標 綠園.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
本节内容 this指针 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
学习目标 1、什么是列类型 2、列类型之数值类型.
计算机编程 信息管理与工程学院 2014年9月.
Presentation transcript:

《C++程序设计》 主讲教师:张玉宏

函数的概念与作用 函数的概念 把很多相关的程序指令放在一起,并加以命名,形成一个执行单元,C++中称呼这种执行单元为function(函数) 函数的目的 1.减少重复撰写类似功能的程序——将常用的算法包装成函数,以重复利用,简化程序的撰写。 2.易于调试和维护——把程序的各个主要部分分成几个模块,可以分别进行开发和测试。 升达大学资讯系

函数的语法 函数间可以相互调用。发起调用动作的函数称为调用函数(calling function),而被调用的函数称为被调函数(called function)从程序开发的观点来看,函数的语法可以分为下列3个部分: 1.函数的声明 建立一个函数的原型(prototype),以告知编译器本程序即将使用的函数名称,以及进出这个函数的数据类型和数量. 2.函数的定义 将函数的内容具体写成程序 3.函数的调用 使用已经定义过的函数 升达大学资讯系

范例程序: // TempConv2.cpp //目的:调用一个简单的函数实现摄氏和华氏温度的转换 #include <iomanip> using std::cin; using std::cout; using std::endl; using std::setw; //-----------函数C2F()的声明--------------------- float C2F(float); //-----------主程序-------------------------------- int main() { float CTemp; cout << " 摄氏 华氏 " << endl ; cout << "-----------------" << endl ; for ( int i = 1 ; i <= 10 ; i++ ) 升达大学资讯系

(接上) { CTemp = 10.0*i; cout << setw(5) << CTemp << " " << setw(5) << C2F(CTemp) << endl ; } cout << "-----------------" << endl ; return 0; //------------函数C2F 的定义---------------------------- float C2F(float C) float F; F = C*9.0/5.0 + 32.0; return F; 升达大学资讯系

函数的声明 下列是几种常见的函数原型 int wanring (); int maxint(int,int,int); int area(int width,int length); Area_2(int,int); void swap(double x,double y); 需要注意的是:函数原型的声明是一个标准的C++语句,所以其后一定用“ ; ”(也就是一个空语句),而真正的函数的定义则不需要。 升达大学资讯系

函数的声明(续) 函数在调用之前一定要先声明,这点和变量在使用前需要声明的情形非常类似。函数的声明也称函数原型,它声明了函数在调用时应该给与的数据类型,以及执行后所返回的数据类型。函数原型的通式为: 返回类型 函数名称(参数数据类型列表) 注意:函数原型的通常需要放置在main()函数之前,可供主程序和其它程序调用,如果放置在main()函数内,则只能从main()内调用。 升达大学资讯系

函数的定义 函数定义的语法和函数的声明一样,只是把原先函数声明后的“;”换成具体的用{ }括起来的复合语句。函数的复合语句与独立成行的单独的语句地位是相等的,因此可以由此理解某些版本的C++语句保留着函数的}后加“;”的习惯,现在的版本可以省略。同时在函数的定义中把要加入完整的函数名称。 定义格式:〔返回类型〕<函数名>(<形参表>) { <语句序列> return 返回值; } 需要注意的:return 返回的值即为函数名(参数列表)所代表的值,二者是一致的。 升达大学资讯系

函数的定义(续) 说明: (1)类型:是函数返回值的数据类型,可为任一基本数据类型或导出数据类型。 如在引例中函数类型为float,即函数的返回值为实型。 注意:函数返回值为整型时,可省略。当函数没有返回值时,可定义其类型为void。 (2)函数名:用户给函数起的名字,其命名规则与标识符相同。 如在引例中函数名为C2F。 (3)形参表:<类型> <形参1>,<类型> <形参2>… 类型为形参的数据类型。在上例中形参C的类型为float。形参也称为形式参数,形参可缺省,构成无参函数,无参函数的定义格式为: 〔类型〕<函数名>(void) {<语句序列> } 升达大学资讯系

函数的调用 调用函数时,必须给与合符参数列表规定的数据,即实参类型必须与形参类型一致,从返回参数的有无,函数的调用可以分为下列两类: (1)没有返回数据时,只用函数名称及函数调用运算符()以及调用运算符内的参数,就可自成一条语句,如: swap(a,b); (2)由函数类型时,则可以将函数的调用放在任何适合该数据类型的语句中,例如赋值语句或算术语句,如: N=maxint(x,y,z); m=2.5*area(x,y); cout << “转换后的温度为"<< C2F(CTemp) << endl 升达大学资讯系

无参函数的实例 # include <iostream.h> void print(void) { cout<<" This is no parameter example \n"; } void main(void) print(); 程序中定义了一个无参函数print,然后在主函数中调用无参函数,程序执行的输出结果是:This is no parameter example 函数体{}:由一系列语句组成。 当函数体为空时,称这种函数为空函数。空函数的定义格式为: 〔类型〕<函数名>(void){ } 函数定义后如何使用,即函数的调用。 升达大学资讯系

不使用函数原型的语法 如果我们把函数的定义置于函数原型的的位置(即在main()函数之前),则此函数的定义兼有函数声明和定义的功能,不再需要在使用函数的原型了。 # include <iostream> # include <cmath> float f(float x) { float y; y=5*x*x+3*x+1; return y;} void main(void) { float z1,z2,x=1; z1=sin(x); z2=f(x); cout<<"sin(x)= "<<z1<<endl; cout<<"f(x+1)= "<<z2<<endl; } 升达大学资讯系

函数调用应该注意的问题 1.函数的调用关系 调用其它函数的函数称为主调函数(如main为主调函数),被其它函数调用的函数称为被调函数(f(x)为被调函数)。 函数间可以互相调用,也可以嵌套调用,但不能调用主函数。 函数不能嵌套定义,即一个函数不能定义在另一个函数内。 2.库函数(标准函数):数学函数、图形处理函数、标准输入/输出函数等 C++将一些数学函数、图形处理函数、标准输入/输出函数作为库函数供用户使用。库函数可分成若干类,每类库函数都集中在一个头文件中加以说明,如数学库函数集中在头文件cmath.h中。 当用户使用任一库函数时,在程序中必须包含相应的头文件,如:# include <cmath>。 升达大学资讯系

例题分析 例题1.用自定义函数求三个整数的最大值。 # include <iostream.h> int max(int x,int y) { int z; if (x>y) z=x; else z=y; return z;} void main(void) { int a,b,c,m; cout<<"Input a,b,c:"; cin>>a>>b>>c; m=max(a,max(b,c));//函数的嵌套调用 cout<<"max(a,b,c)= "<<m<<endl;} 注:教材p34页例3.4有另一种写法。 升达大学资讯系

函数参数的传送方式 在C++中,实参和形参间数据传送的方式有三种:传值调用(pass by vaule)、引用传送(call by reference)和传地址。这里先介绍传值调用方式和引用传送,后一种方式在后文中介绍。 1.传值调用 实参传送给形参的数据传送过程: (1)调用函数时,先为形参分配存储单元,后将实参值传递给形参; (2)函数执行过程中均为形参参与运算; (3)函数调用后,形参所对应的存储单元被释放,实参保持原来的值不变。 其示意图如下所示: 升达大学资讯系

当函数被调用时,参数首先被复制到内存的一个特殊区域,称之为堆栈(stack)如图中步骤1,且程序的执行次序和控制劝都交给被调用的函数,如C2F()。被调用的函数先将参数(float c)初始化为堆栈的值(如步骤2),才开始进行运算。在运算完毕后才将结果复制一份到堆栈内,如步骤3,接着将控制权交给被调用函数。调用函数这时再把堆栈的结果复制一份回来(如步骤4),并恢复原先的执行次序。由于这种传值的调用方式,参数的值被层层复制,因此被调用的函数内对参数的任何更动都不会影响调用函数内的参数。 图 3.1 函数参数的传递方式 升达大学资讯系

传值调用流程的说明 当函数被调用时,参数首先被复制到内存的一个特殊区域,称之为堆栈(stack)如图中步骤1,且程序的执行次序和控制劝都交给被调用的函数,如C2F()。被调用的函数先将参数(float c)初始化为堆栈的值(如步骤2),才开始进行运算。在运算完毕后才将结果复制一份到堆栈内,如步骤3,接着将控制权交给被调用函数。调用函数这时再把堆栈的结果复制一份回来(如步骤4),并恢复原先的执行次序。由于这种传值的调用方式,参数的值被层层复制,因此被调用的函数内对参数的任何更动都不会影响调用函数内的参数。 升达大学资讯系

函数的return语句 语句格式:return <表达式>; 或:return (<表达式>); 作用:返回表达式的值,结束函数执行,并将控制转移到调用函数的地方继续执行。 例如:比较两个整数大小的max函数中可简写成如下形式: int max(int x,int y) { return (x>y?x:y); } 升达大学资讯系

函数的return语句(续) 说明: (1)不需函数返回值时可不写return语句; (2)函数中可有多个return语句; 例如:max( int x,int y) { if (x>y) return x; else return y;} (3)默认的函数返回值为整型(此时,可不指定返回值的类型) 例如,上面的max函数可定义为: max(int x,int y) {…} (4)当函数类型与return中表达式值类型不同时,表达式的值自动转换成函数返回值的类型。 升达大学资讯系

以引用的方式调用 利用传值调用我们可以写出很多有用的程序,但是我们也注意到了利用return语句只能回传一个值的限制。此外,有些时候我们也想改变参数的数值。要突破这些限制,可以使用引用(reference)的技巧。 引用是同一个变量的别名(alias)。例如: int N; int& M=N; //A 定义了变量N,同时定义了N的引用M。这里的&称为引用运算符,表示M和N所代表的变量位于同一个地址上。对于M所作的变化都等同于直接作用于N上,反之亦然。A语句也可以写成:int &M=N; 升达大学资讯系

以引用的方式调用(续) 也就是说,下面两个函数的标头部分(header line)是一样的: int fnc(int& N;float& x) int fnc(int &N;float &x) 特别注意的是:引用运算符和取地址运算符都使用相同的符号“&”,但是它们的意义却不是一样的。 int N; int M= &N; //所代表的意义是将N的地址(32bit)存入整数M中。 升达大学资讯系

一个引用的例程 // Alias.cpp #include <iomanip> using std::cin; using std::cout; using std::endl; int main(){ int N = 10; int& M = N; cout<< "M 的值原来是:"<< M << endl; cout<< "N 的值原来是:"<< N << endl; N = 5; cout<< "执行 “N = 5;” 之后" << endl; cout<< "M 的值目前是:" << M <<endl; M = 2; cout<< "执行 “M = 2;” 之后" << endl; cout<< "N 的值目前是:" << N <<endl; } 运行结果 升达大学资讯系

关于“引用”的讨论 一般而言,为了避免在不无意中变更调用函数内的变量值,并不鼓励用引用调用的方式来传递参数,除非以下三种情况: 1.参数本身必须改变 2.要回传两个以上的值 3.有大量参数需要传递,如果不用引用,则将耗费大量时间在参数的复制上。例如,参数为大型向量或矩阵的情况 升达大学资讯系

一个利用引用传值的例程 升达大学资讯系 SWAP2(A, B); #include <iostream> cout << "执行过 SWAP2()\n"; cout << " A 的值是:" << A<< "\n B 的值是:" << B << endl; } //------------------------- void Swap (int& x, int& y) { int Temp; Temp = x; x = y; y = Temp;} void SWAP2 (int x, int y) { int Temp; #include <iostream> using std::cin; // Swap.cpp using std::cout; using std::endl; void Swap (int&, int&); void SWAP2 (int, int); int main() { int A=5, B=10; Swap(A, B); cout << "执行过 Swap()\n"; cout << " A 的值是:" << A<< "\n B 的值是:"<< B << endl; cout << endl; 升达大学资讯系

inline(内联)函数 在我们以往的函数调用时,程序的主控权就会交给被调函数,执行完毕后才把主控权交还给调用函数。在这个过程中,必须在堆栈里记录每个阶段的执行程序代码的位置以待稍后接着执行;这个记录执行指令程序代码的位置的变量称为程序指针(instruction pointer,IP)或程序计数器(program counter,简称PC)。主控权的交接,以及参数的复制都需要时间。对于这样额外的负担,C++提供了一个适用于函数的特殊的语法,称为内联函数(inline function) 升达大学资讯系

inline函数(续) inline 函数的实际运作和一般的函数很不一样。在编译时,其程序代码在每个调用的地方直接展开加入,因此不需要浪费时间进行主控权的转换,直接变成调用程序的一段复合语句。 inline 函数的定义非常简单,只要直接在函数的定义前加上关键词“inline”就可以。 升达大学资讯系

inline 函数例程 运行结果 升达大学资讯系 // Inline.cpp #include <iomanip> using std::cin; using std::cout; using std::endl; using std::setw; inline float C2F(float C) // Inline 函数的声明和定义 { return C*9.0/5.0 + 32.0; } int main() {float CTemp; // 主程序 cout << " 摄氏 华氏 " << endl ; cout << "-----------------" << endl ; for ( int i = 1 ; i <= 10 ; i++ ) {CTemp = 10.0*i; cout << setw(5) << CTemp << " " << setw(5) << C2F(CTemp) << endl ;} cout << "-----------------" << endl ;} 运行结果 升达大学资讯系

变量的适用范围和生存期 一、局部变量 函数的主体可看为一个复合语句,因此包括函数表头部分的参数列表内所定义的传值,都只在该函数内才适用。在传值的情况下,每一个函数都占用自己独立的内存空间,函数内变量的工作空间不会与其它函数的工作空间重叠,这些变量称为局部变量(local variables)。 局部变量的声明分为auto,static和register三个存储种类: 1.auto是automatic的缩写,是所有函数内变量的默认存储方式。Auto变量只在函数被调用时才存在,该函数结束后就消失,不会保留最后的值 。 升达大学资讯系

变量的适用范围和生存期(续) 2.被声明为“static(静态)”的局部变量并不随函数调用结束而消失。除非整个程序结束,否则static变量的值具有连续性。也就是说,每一次函数被调用时, static变量的值是上一次调用结束时的值。 3.“register”原本是CPU内的一种内存,称之为寄存器。如果某个变量使用频繁的话,可以将其声明为register变量保留在CPU内,以提升函数的执行速度。但是寄存器的数量很有限,因此编译器可能会忽略这个声明。一般来说,一个函数内的变量数量很多,而且新一代的CPU内含有高速缓存(cache memory)以提升执行效率,因此此项功能的实际效益并不大。 需要说明的是: register不放在主存储器内,因此没有标准的地址 ,也就是说取址运算符号“&”不可以用在它上面 升达大学资讯系

一个关于局部变量的例程 // Local.cpp #include <iostream.h> using namespace std; void TestLocal(); int main() { for (int i=1; i<=3; i++) { cout << "第(" << i << ")次:" << endl; TestLocal(); cout << endl;} return 0; } 升达大学资讯系

一个关于局部变量的例程(续) 运行结果 void TestLocal() { int A = 1; static int S = 1; register int R = 1; cout << " A 的值是 " << A << endl; cout << " S 的值是 " << S << endl; cout << " R 的值是 " << R << endl; for (register int i=0; i<1000; i++) R += 2; cout << " 计算后 R 的值是 " << R << endl; A++; S++; R++; return; } 运行结果 升达大学资讯系

运行结果 升达大学资讯系

二、全局变量 如果把变量的声明放在所有的函数之前,则这些变量值变量称为全局变量(global variables)可以让其后的所有函数共享。全局变量的例程: 升达大学资讯系

二、全局变量(续) 运行结果 升达大学资讯系

全局变量(续) 讨论: 1.可以看出main()函数中的全局变量GLOBAL和函数TestFnc()的变量GLOBAL是共享的。函数TestFnc()的变化也反映在main()中。 2.函数TestFnc()中声明一个和main()函数一样名称的整数,并在TestFnc()中改变,但这个改变并没有反映到main()中,这个结果显示即使局部变量和全局变量有相同的名字,实际上它们是两个完全独立的变量。也就是局部变量在函数中覆盖全局变量,且不影响全局变量的值。 3.如果全局变量想在函数中不被局部变量覆盖,则可以通过在其变量前使用范围确认运算符号“::”,如程序中的“::GLOBAL_2” 升达大学资讯系

全局变量 提示: 1.全局变量虽然好用,但它破坏了函数原先所具有的独立性和严格的数据输入输出控制。特别是当程序很庞大的时候,如果对全局变量的使用不加以控制,将使得程序调试变得非常困难。因此,在撰写大型程序时,全局变量的数量常常严格控制在10个以下,而且往往全部大写字母,或故意使用很长的名称来突出显示。 2.如果没有对全局变量在声明时进行赋予初始值,则全局变量会在编译时被自动初始化为0,这个特性和static局部变量是一样的。但是,程序设计人员应该将变量的初始化视为自己的工作,而不是交给编译器来完成。 升达大学资讯系

全局变量的储存种类 全局变量在程序执行期间一直都存在,所以没有生存期的问题,对于一个大型的程序,通常把它分成好几个文件分别来撰写。函数可以放在同一个文件里,也可以在很多文件分别有不同的函数。每个存有C++程序的文件,不管它是主程序还是函数,都称为一个编译单元(compile unit)。 为了规范文件间变量的适用范围,有extern和static两种存储类型的声明: extern 全局变量——声明这个变量已经在其它文件内定义过了。对于变量而言,它是一种声明(declaration)而不是定义(definition),因为extern 全局变量的声明并不会在内存中使用新的记忆空间,而是使用它所指定的同一个变量。 升达大学资讯系

全局变量的储存种类(续) static 全局变量——声明这个全局变量只能在本文件中适用。这个语法在新的ANSI/ISO规范中虽然暂时保留,但即将淘汰,改用名称空间(namespace)的方式处理。后续课程将详细讲述名称空间 提示: 1.由于static 和extern是完全相反的声明,不同同时使用。 2.static 全局变量和函数内的static 局部变量都使用关键词static ,但意义决然不同: static 全局变量——声明全局变量只能在本文件中适用 static 局部变量——不随函数的调用结束而消失。除非整个程序结束,否则static 局部变量的值都具有连续性。 升达大学资讯系

范例程序(1-1) 升达大学资讯系

范例程序(1-2) 由于ExternB内的Func2()内有extern int An;的 运行结果 升达大学资讯系

运行结果 升达大学资讯系

本讲完毕 升达大学资讯系