第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性.

Slides:



Advertisements
Similar presentations
第九章 指针 西安工程大学.
Advertisements

第8章 函数 信息管理系.
第五章 函数 本章学习重点:  函数的定义与函数声明;  函数的调用;  函数的嵌套调用与递归调用;  数组作为函数参数;
Oracle数据库 Oracle 子程序.
第6章 指针 6.1 指针的概念 6.2 变量与指针 6.3 数组与指针 6.4 字符串与指针 6.5 函数与指针 6.6 返回指针值的函数
6.4 字符串与指针 1. 用字符数组存放一个字符串.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
第九章 指针 目录 指针与指针变量的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量
C语言程序设计 第八章 函数.
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
第5章 函数及变量的存储类别 5.0 概述 5.1函数的定义 5.2函数调用 5.3变量的作用域和存储类别 5.4内部函数和外部函数
第八章 函数 §8.1 概述 一个较大程序一般分为若干个程序模块,每一个模块实现一个特定的功能。所有的高级语言中都有子程序的概念,在C中子程序就是函数。 一个C程序可由一个主函数和若干个函数构成,由主函数调用其它函数,其它函数也可以相互调用.
授课老师:龚涛 信息科学与技术学院 2017年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
函數(一) 自訂函數、遞迴函數 綠園.
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
Chap 10 函数与程序结构 10.1 函数的组织 10.2 递归函数 10.3 宏定义 10.4 编译预处理.
C语言程序设计基础 刘新国.
第 十 章 指 针.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
第7章 函 数 本章要点: C语言程序结构和特点 函数的定义 函数的返回值与函数的类型 函数的调用及参数的传递关系 函数的嵌套与递归
走进编程 程序的顺序结构(二).
C程序设计 谭浩强 著 清华大学出版社.
第八章 函数.
辅导课程六.
第7章 函 数 为什么要使用函数? 函数定义、调用、声明 局部变量和全局变量 变量的存储类别 内部函数和外部函数 函数的嵌套调用和递归调用
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
第二章 C++对C 在非面向对象方面的改进 更简洁,更安全.
第7章 用函数实现模块化程序设计 7.1为什么要用函数 7.2怎样定义函数 7.3调用函数 7.4对被调用函数的声明和函数原型
第五章 函数 5.1 函数的定义、调用与说明 5.2 函数间参数传递 5.3 递归函数 5.4 函数参数缺省 5.5 函数重载
第二章 Java语言基础.
第七章 函数 西安工程大学.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
第七章 操作符重载 胡昊 南京大学计算机系软件所.
实验九 函数嵌套、函数参数 第27讲 C程序设计 Main() { int x,y; X=10; y=x*x+1;
C++大学基础教程 第3章 C++控制语句 北京科技大学 信息基础科学系.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
THE C PROGRAMMING LANGUAGE
C++语言程序设计 第三章 函数.
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
第7章 函 数 7.1 函数的定义与调用 7.2 函数的嵌套调用与递归调用 7.3 数组作为函数参数 7.4 内部变量与外部变量
C语言程序设计.
目录 7.1 用户自定义函数的种类 7.2 函数的定义 7.3 被调函数的声明 7.4 函数的调用 7.5 函数的嵌套调用
第六章 指针 C++程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第五章 函 数 要点:掌握函数的定义,函数的原形,函数的返回值,函数的调用,函数的形式参数和实际参数之间的关系;掌握函数重载的使用方法,关键字inline的含义与使用,掌握变量的作用域与生存期,了解函数的作用域。
C程序设计.
第4章 Excel电子表格制作软件 4.4 函数(一).
第九节 赋值运算符和赋值表达式.
3.16 枚举算法及其程序实现 ——数组的作用.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第二章 高级函数特性.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第7章 用函数实现模块化程序设计 7.1为什么要用函数 7.2怎样定义函数 7.3调用函数 7.4对被调用函数的声明和函数原型
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二节 函数的极限 一、函数极限的定义 二、函数极限的性质 三、小结 思考题.
本节内容 结构体.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
C++语言程序设计教程 第4章 函数 第4章 函数.
计算机编程 信息管理与工程学院 2014年9月.
Presentation transcript:

第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性

学习目标 理解函数的作用以及分类; 熟练掌握函数的定义、声明、调用; 理解形参和实参的作用,以及三种参数传递方式的区别与使用; 掌握数组作函数参数声明、调用形式; 掌握默认值参数的定义与作用; 理解函数的递归调用,熟悉递归程序的编写; 理解并掌握函数重载的作用和形式; 理解局部变量和全局变量; 理解变量的存储类别,区分自动、静态、寄存器以及外部 变量的特点。

第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性

8.1 函数的定义与调用 如何解决这种冗余呢? 引入—为什么需要函数? void main() { int m,n,i,sum; cout<<"m="; cin>>m; for(i=1,sum=0;i<=m;i++) sum=sum+i; cout<<"1+…+"<<m<<"="<<sum<<endl; cout<<"n="; cin>>n; for(i=1,sum=0;i<=n;i++) cout<<"1+…+"<<n<<"="<<sum<<endl; } 如何解决这种冗余呢?

函数的定义 函数 是程序代码的自包含单元,用于完成某一特定任务。 是C++的基本组成模块。 用于完成某种操作或计算某个数值。

函数的作用 函数 降低程序复杂度 增强代码的重用性和可维护性 提高程序开发效率

函数的分类 标准函数 定义角度 自定义函数 函数 无参函数 参数角度 有参函数

函数的分类 标准函数 是C++编译系统预定义的函数,也称库函数。 用户可以直接使用系统提供的库函数,使用时需在程 序中包含相应的头文件。 用户可以直接使用系统提供的库函数,使用时需在程 序中包含相应的头文件。 如 #include<iostream.h>等。 库函数有很多个,例如: 数学计算库函数 #include<math.h> 字符串处理库函数 #include<string.h> 标准输入输出库函数 #include<iostream.h>

函数的分类 自定义函数 无参函数 有参函数 程序设计中由用户自己定义函数。 是程序设计中的主要环节。 函数没有参数传入,执行后也没有返回值。 主要是为完成某种操作。 有参函数 函数有参数传入,执行后有返回值。 可完成操作或计算数值。

函数的定义方式 函数的定义: 函数类型 形参列表 函数类型 函数名(形参列表) { 函数体; } 函数执行后返回值的类型; 无返回值时,使用“void”; 形参列表 函数接收的数据; 若无数据接收则为空,或写为“void”; 否则格式为:(类型1 参数1 ,类型2 参数2 ,……) 函数类型 函数名(形参列表) { 函数体; }

函数的调用方式 函数的调用: 5 a 8 b 实参 x y 形参 5 8 实参列表的格式:实参1,实参2,… 没有参数时不能省略圆括号。 函数名(实参列表) 5 a 8 b 实参 x y 形参 5 8

函数的形参 形参—定义函数时给出的参数 形参只是虚拟的参数,在函数未调用之前,没有任何实际的值。 形参必须要定义类型。 未调用函数时,形参不占内存单元,只在函数开始调用时,形参才被分配内存单元。 调用结束后,形参所占用的内存单元被释放。 形参只作用于被调函数,可以在别的函数中使用相同的变量名。

函数的实参 实参—调用时给函数传递的实际参数。 实参对形参变量的传递是“值传递”,即单向传递。 在内存中实参、形参分占不同的单元。 实参的类型可以是常量、变量以及表达式;不管是哪种情况,在调用时实参必须是一个确定的值。 实参是按顺序逐个传递给形参的,其个数、类型必须与形参一致。 实参对形参变量的传递是“值传递”,即单向传递。 在内存中实参、形参分占不同的单元。

例: 形参实参类型相等,一一对应 void fun(int x, int y) { x=x*10; y=y+x; cout<<x<<‘\t’<<y<<endl; } void main(void) { int a=2, b=3; fun(a+b,a*b); cout<<a<<‘\t’<<b<<endl; 形参实参类型相等,一一对应 x y 50 5 56 6 5 6 2 3 a b 50 56 2 3

例: 两个被调函数主要用于完成打印操作。 函数类型 函数名 函数形参 void printstar (void ) { cout<<“* * * * * * * * * * *\n”; } void print_message (void) { cout<<“ How do you do! \n”; } void main(void ) { printstar ( ); print_message ( ); printstar( ); } 输出: * * * * * * * * * * * How do you do! * * * * * * * * * * * 调用函数 调用函数 调用函数

函数的返回值 函数的返回值 通过return语句获得。 函数只能有唯一的返回值。 函数返回值的类型就是函数的类型。

函数的返回值 函数体 int max ( int x, int y) { int z; z=x>y?x:y; return z; } 如果有函数返回值, 函数的类型就是返回值的类型 int max ( int x, int y) { int z; z=x>y?x:y; return z; } 如果有函数返回值,返回值就是函数值,必须唯一。 函数体的类型、形式参数的类型必须在函数的定义中体现出来。 函数体 参数(多个) 函数值(唯一)

函数的返回值 若函数体内没有return语句,就一直执行到函数体的末尾,然后返回到主调函数的调用处 int max ( int x, int y) { if (x>y) return x ; else return y; } int add ( int a, int b) { return (a+b); } 函数的返回值为唯一值 函数的返回值为表达式 若函数体内没有return语句,就一直执行到函数体的末尾,然后返回到主调函数的调用处

8.1 函数的定义与调用 调用另一函数(即被调用函数)需要具备哪些条 件呢? 被调用的函数在调用的时候必须是已存在的函数 调用另一函数(即被调用函数)需要具备哪些条 件呢? 被调用的函数在调用的时候必须是已存在的函数 如果使用库函数,必须用 #include < math.h> 函数调用遵循先定义、后调用的原则,即被调函数应出 现在主调函数之前。 如果使用用户自己定义的函数,而该函数与调用它的函 数(即主调函数)在同一个程序中且位置在主调函数之 后,则必须在调用此函数之前对被调用的函数作声明。

实参传递的是一个具体的值,不必说明参数类型 函数先定义后调用 float max(float x, float y) { float z; z=(x>y)? x : y ; return z; } 形参必须说明参数类型 被调函数先定义 void main (void) { float a,b, c; cin>>a>>b; c=max (a+b , a*b) ; cout<<“The max is”<<c<<endl; } 定义之后再调用 实参传递的是一个具体的值,不必说明参数类型

函数先使用后定义时必须要有声明 定义是一个完整的函数单位,而原型说明仅仅是说明函数的返回值及形参的类型。 void main (void) { float a,b, c; float max (float, float); cin>>a>>b; c=max (a,b) ; cout<<“The max is”<<c<<endl; } 函数原型声明 函数定义 float max (float x, float y) { float z; z=(x>y)? x : y ; return z; } 定义是一个完整的函数单位,而原型说明仅仅是说明函数的返回值及形参的类型。

函数的嵌套调用 C++语言中,所有函数都是平行独立的,无主次 、相互包含之分。函数可以嵌套调用,不可嵌套 定义。 int min ( int a, int b) { return ( a<b? a: b); } int max ( int a, int b) { int c; int min ( int a, int b) { return ( a<b? a: b); } c=min(a,b); return ( a>b? a : b); 嵌套定义 平行定义 int max ( int a, int b) { int c; c=min(a,b); return ( a>b? a : b); } 嵌套调用

第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性

传值调用举例 输出: 7 6 7 2 7 5 void main(void) x 7 j 6 void main(void) { int i=2, x=5, j=7; void fun(int,int); fun ( j, 6); cout<<i<<‘\t’<< j<<‘\t’<< x<<endl; } void fun ( int i, int j) { int x=7; cout<<i<<‘\t’<< j<<‘\t’<<x<<endl; j x i 7 7 6 输出: 7 6 7 2 7 5

8.2 函数的参数 函数的参数传递方式---(二)传地址调用 1、形参类型:指针变量 2、实参类型:数据的地址值 3、传递方式:将实参的地址传递给形参; 4、特点:函数中对形参的改变会影响实参的值。

传地址调用举例 void prt(int *x , int *y , int *z) { cout<< ++*x<<‘,’<< ++*y<<‘,’<<*(z++)<<endl; } int a=10, b=40, c=20; void main(void) prt (&a, &b, &c); 11, 41, 20 12, 42, 20 x &a a 10 ++*x: *x=*x+1 *(z++): *z ; z=z+1

传地址应用1—数组名作函数参数 数组名可以作函数的实参和形参,传递的是数组 的地址。这样,实参、形参共同指向同一段内存 单元,内存单元中的数据发生变化,这种变化会 反应到主调函数内。 在函数调用时,形参数组并没有另外开辟新的存 储单元,而是以实参数组的首地址作为形参数组 的首地址。这样形参数组的元素值发生了变化也 就使实参数组的元素值发生了变化。

(1)形参实参都用数组名 void main(void) { int array[10]; 形参数组,必须进行类型说明 ...... f(array, 10); ..... } 形参数组,必须进行类型说明 f(int arr[ ], int n) { ...... } 实参数组 用数组名作形参,因为接收的是地址,所以可以不指定具体的元素个数。

(1)形参实参都用数组名 指向同一存储区间 array[0] array[1] array[2] array[3] array[4] 2000H array[0] 2004H array[1] 2008H array[2] 200CH array[3] 2010H array[4] 2014H array[5] 201CH array[6] 2020H array[7] 2024H array[8] 2028H array[9]

(2)实参用数组名,形参用指针变量 void main(void) { int a [10]; f(int *x, int n ) { ...... f(a, 10); ..... } f(int *x, int n ) { ...... } 形参指针 实参数组

(3) 形参实参都用指针变量 形参指针 void main(void) { int a [10],*p; f(int *x, int n ) p=a; ...... f(p, 10); ..... } f(int *x, int n ) { ...... } 实参指针 实参指针变量调用前必须赋值

(4)实参为指针变量,形参为数组名 void main(void) 形参数组 { int a [10],*p; p=a; ...... f(p, 10); ..... } 形参数组 f(int x[ ], int n ) { ...... } 实参指针

下面程序实现了将数组中的n个数按相反顺序存放。 void inv(int x[ ], int n) { int t, i, j, m=(n-1)/2; for (i=0;i<=m; i++) { j=n-1-i; t=x[i]; x[i]=x[j]; x[j]=t; } x与a数组指向同一段内存 2 4 5 7 6 11 9 x[9] x[8] x[7] x[6] x[5] x[4] x[3] x[2] x[1] x[0] a[9] a[8] a[7] a[6] a[5] a[4] a[3] a[2] a[1] a[0] x, a 3 void main(void) { int i, a[10]={3,7,9,11,0,6,7,5,4,2}; inv(a,10); for (i=0;i<10; i++) cout<<a[i]<<‘\t’; }

i p j void inv(int *x, int n) { int *p, t, *i, *j, m=(n-1)/2; i=x; j=x+n-1; p=x+m; for (; i<=p; i++,j--) { t=*i; *i=*j; *j=t; } 用指针变量来接受地址 2 4 5 7 6 11 9 x[9] x[8] x[7] x[6] x[5] x[4] x[3] x[2] x[1] x[0] a[9] a[8] a[7] a[6] a[5] a[4] a[3] a[2] a[1] a[0] x, a 3 i j p void main(void) { int i, a[10]={3,7,9,11,0,6,7,5,4,2}; inv(a,10); for (i=0;i<10; i++) cout<<a[i]<<‘\t’; } 34

传地址应用2— 字符串指针作函数参数 将一个字符串从一个函数传递到另一个函 数,可以用地址传递的办法。即用字符数 组名作参数或用指向字符串的指针变量作 参数。在被调函数中可以改变原字符串的 内容。

{ char a[ ]={“I am a teacher”}; char b[ ]={“You are a student”}; 将字符串a复制到字符串b。 from a void main(void) { char a[ ]={“I am a teacher”}; char b[ ]={“You are a student”}; copy_string(a , b); cout<<a<<endl; cout<<b<<endl; } to b from与a一个地址,to与b一个地址 copy_string( char from[],char to[]) { int i; for (i=0; from[i]!=‘\0’; i++) to[i]=from[i]; to[i]=‘\0’; }

也可以用字符指针来接受数组名 for(; *from++=*to++; ) ; 将字符串a复制到字符串b。 copy_string(char *from, char *to) { for ( ; *from!=‘\0’; ) *to++=*from++; *to=‘\0’; } for(; *from++=*to++; ) ; void main(void) { char a[ ]={“I am a teacher”}; char b[ ]={“You are a student”}; copy_string(a,b); cout<<a<<endl; cout<<b<<endl; } a from b to 也可以用字符指针来接受数组名

8.2 函数的参数 函数的参数传递方式---(三)引用调用 1、形参类型:引用型的变量 2、实参类型:变量 3、传递方式:将实参变量名赋给形参引用 4、特点:函数中对形参的操作就是对实参的操作

引用调用举例 输出: 5 3 引用作为形参,实参是变量而不是地址,这与指针变量作形参不一样。 void change(int &x, int &y)//x,y是实参a,b的别名 { int t; t=x; x=y; y=t; } void main(void) { int a=3,b=5; change(a,b); //实参为变量 cout<<a<<‘\t’<<b<<endl; a b 5 5 3 3 y x t 3 输出: 5 3 引用作为形参,实参是变量而不是地址,这与指针变量作形参不一样。

例: void f1( int *px) {*px+=10;} void f2(int &xx) { xx+=10;} void main(void) { int x=0; cout<<"x="<<x<<endl; f1(&x); f2(x); } x=0 x=10 x=20

函数的返回值为指针 char *strchr(char *str , char ch) { while(*str != ch && *str != '\0') { str++ ; } return str ; }

第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性

函数的重载 函数重载的概念 同一个函数名定义多个不同函数的实现。 实现“一物多用”,即同一个函数名实现多种函 数功能。

例1: int add (int a, int b) { return (a+b); } double add (double a, double b) { return(a+b); }

函数的重载 函数重载的原则 函数名相同 参数的类型或数目至少有其一个不同 编译系统根据函数实参的类型和数目从左向右进 行匹配,调用相应的函数。

例2: int fun(int a, int b) void main(void) { { return a+b; } void main(void) { cout<<fun(3,5)<<endl; cout<<fun(5)<<endl; } int fun (int a) { return a*a; } 8 25

函数重载的原则 函数重载不以函数的返回值类型区分。 void move(int a); int move(int a); 重载非法 函数重载不以参数中的关键字区分。 在定义重载函数时,需要注意如果两个函数的函数名称、参数个数、参数类型相同,函数的返回值类型不同,编译时会出现错误,即函数重载不以函数的返回值类型区分。 函数重载不以参数中的关键字区分。 void move (const int a); void move(int a); 重载非法

重载函数 double Add(double one, double two); int Add(int one, int two); int main() {   cout<<Add(2.51,3.652);  cout<<endl; cout<<Add(2,5);  cout<<Add(5);    return 0; } 调用double Add(double one,double two)函数 函数重载是多个函数具有相同的名称,但函数的参数不同。在调用函数时,编译器会根据参数的个数、参数的类型区分调用哪个函数。下面根据“函数重载实现多态性”来举例说明。 调用int Add(int one,int two)函数 调用int Add(int one)函数

函数的递归调用 函数的递归调用 函数递归调用的分类 函数 函数递归调用的作用 A函数 B函数 在函数体中直接或间接调用函数本身。 直接递归 直接递归函数直接调用其本身 间接递归A函数调用B函数,而B函数 又调用A函数。 函数递归调用的作用 使用函数递归能够简化复杂的数学运算 直接递归 函数 A函数 B函数 间接递归

例3: 1 1 1 2 2 3 6 4 24 5 120 int factorial(int n); int main() { cout<<factorial(5)<<endl; return 0; } int factorial(int n) if ((n==0)||(n==1)) return 1; else return n*factorial(n-1); n factorial() 1 1 1 2 2 3 6 4 24 5 120

例4: 假设:一对刚出生的小兔一个月后就能长成大兔,再 过一个月就能生下一对小兔,并且此后每个月都生一 对小兔,一年内没有发生死亡。 问:一对刚出生的兔子,一年内繁殖成多少对兔子? 月份 1 2 3 4 5 6 7 8 9 10 11 12 对数 13 21 34 55 89 144 F1=1 (n=1) F2=1 (n=2) Fn=Fn-1+Fn-2 (n>=3) 斐波那契(Fibonacci)数列 斐波那契(1175-1250)

例4: int fib(int n); void main() { int n; cout<<“Please input n:”; cin>>n; cout<<“fib(“<<n<<”)=”<<fib(n)<<endl; } int fib(int n) if (n==1||n==2) return 1; else return fib(n-2)+fib(n-1); n fib(n) 12 fib(12) 11 fib(11) 10 fib(10) 9 fib(9) 8 fib(8) 7 fib(7) 6 fib(6) 5 fib(5) 4 fib(4) 3 fib(3) 2 fib(2)=1 1 fib(1)=1

第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性

作用域 作用域是指程序中所说明的标识符在哪一个区间 内有效,即在哪一个区间内可以使用该标识符。 在C++中,作用域共分为五类: 块作用域 作用域是指程序中所说明的标识符在哪一个区间 内有效,即在哪一个区间内可以使用该标识符。 在C++中,作用域共分为五类: 块作用域 文件作用域 函数原型作用域 函数作用域 类的作用域

块作用域 我们把用花括号括起来的一部分程序称为一个块。 在块内说明的标识符,只能在该块内引用,即其作 用域在该块内,开始于标识符的说明处,结束于块 的结尾处。 在一个函数内部定义的变量或在一个块中定义的变 量称为局部变量 具有块作用域的标识符在其作用域内,将屏蔽其他 同名标识符,即 变量名相同,局部更优先。

块作用域举例 int a = 0; for (int i = 0;i < 10;i++) { int b = i; b++; a += b; } 变量b具有块作用域,当程序的控制流离开了这个循环,就是for循环结束时,这个变量b就被销毁了,不存在了。在for循环的外部再引用变量b的话,程序就会报错:"变量b未定义".

函数作用域 在函数内或复合语句内部定义的变量,其作用域 是从定义的位置起到函数体或复合语句的结束。 形参也是局部变量。 在函数内或复合语句内部定义的变量,其作用域 是从定义的位置起到函数体或复合语句的结束。 形参也是局部变量。 float f1( int a) { int b,c; ..... } void main(void ) { int m, n; ..... } a,b,c有效 m,n有效 float f2( int x, int y) { int i, j; ..... } x,y,i,j 有效

文件作用域 在函数外定义的变量称为全局变量。 全局变量的作用域称为文件作用域,即在整个文件中都是可以访问的。 其缺省的作用范围是:从定义全局变量的位置开始到该源程序文件结束。 当在块作用域内的变量与全局变量同名时,局部变量优先。

int p=1, q=5; float f1( int a) { int b,c; ..... } 全局变量 a,b,c有效 局部变量 p,q有效 char c1,c2; main( ) { int m, n; ..... } c1,c2有效 m,n有效

函数作用域 主函数main中定义的变量,也只在主函数中有 效,同样属于局部变量。 不同的函数可以使用相同名字的局部变量,它 们在内存中分属不同的存储区间,互不干扰。 void main(void) { int x=10; { int x=20; cout<<x<<endl; } x 10 x 20 20 10 60

生存期 程序区 静态存储区 动态存储区 全局变量 动态存储变量 作用域 生存期 局部变量 静态存储变量 静态存储:在文件运行期间有固定的存储空间,直到文件运行结束。 动态存储:在程序运行期间根据需要分配存储空间,函数结束后立即释放空间。若一个函数在程序中被调用两次,则每次分配的单元有可能不同。 程序区 静态存储区 动态存储区 静态局部变量 全局变量 动态局部变量

变量或函数的存储类型 默认存储方式是auto类型! auto static extern register 存贮位置 内存堆栈 CPU的寄存器 生存期 与函数同时 与文件同时 与程序同时 连结性 无连接性 本文件内部连结性 多文件全局连结性 默认存储方式是auto类型!

5 9 int fun(int a) { int c; static int b=3; c=a+ b++; return c; } void main(void) { int x=2, y; y=fun(x); cout<<y<<endl; y=fun(x+3); 只赋一次初值 5 2 4 5 3 9 5 a a b c c 输出: 5 2 9 5 9 x y 变量b是静态局部变量,在内存一旦开辟空间,就不会释放,空间值一直保留

第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性

思考题 编写程序,分别计算下列函数的值(x从键 盘输入) (1) (2) 当最后一项小于0.00001时,累加结束。 网络课程平台http://course.cn/G2S/Template/View.aspx?action=view&courseType=0&courseId=2272