Cchap3函数教学讲解课件

上传人:风*** 文档编号:240745434 上传时间:2024-05-04 格式:PPTX 页数:55 大小:465.64KB
返回 下载 相关 举报
Cchap3函数教学讲解课件_第1页
第1页 / 共55页
Cchap3函数教学讲解课件_第2页
第2页 / 共55页
Cchap3函数教学讲解课件_第3页
第3页 / 共55页
点击查看更多>>
资源描述
J 函数的定义函数的定义J 函数原型声明函数原型声明J 函数调用及参数传递函数调用及参数传递*J 函数的嵌套、递归调用函数的嵌套、递归调用J 内联函数内联函数J 函数重载函数重载J 有默认参数的函数有默认参数的函数J 作用域与存储类别作用域与存储类别J 指针与函数指针与函数Part 4 函数函数函数概念的引入函数概念的引入 函数:独立的功能函数:独立的功能,构成的程构成的程序的基本单位。序的基本单位。通用:通用:标准函数(函数库)标准函数(函数库):sqrt,fabs,strcat,strlen,用户自定义函数用户自定义函数#includevoid main()double x,m=1,sum=0;cinx;m=1;for(int i=0;i7;i+)m*=x;/m=x7sum+=4*m;m=1;for(i=0;i5;i+)m*=x;/m=x4sum+=2*m;m=1;for(i=0;i4;i+)m*=x;/m=x3sum+=3*m;coutsumendl;/求求4x7+2x5+3x4 一段程序被执行了多次,完一段程序被执行了多次,完成一个独立的功能成一个独立的功能优化程序结构优化程序结构#includevoid main()double x,m=1,sum=0;cinx;m=power(x,7);sum+=4*m;m=power(x,5);sum+=2*m;m=power(x,4);sum+=3*m;coutsumendl;double power(double x,int n)double s=1;for(int i=1;i=n;i+)s*=x;return s;主调函数主调函数被调函数被调函数函数的引入函数的引入n函数定义形式函数定义形式数据类型数据类型 函数名(形参列表)函数名(形参列表)语句序列语句序列 n函数是一段具有独立功能的程序模块函数是一段具有独立功能的程序模块1 函数定义函数定义(不允许嵌套定义不允许嵌套定义不允许嵌套定义不允许嵌套定义)函数说明函数说明函数说明函数说明函数体函数体函数体函数体double power(double x,int n)double s=1;for(int i=1;i=n;i+)s*=x;return s;#includevoid main()double x,s;int n;cinxn;s=power(x,n);coutsendl;函数说明:函数说明:函数说明:函数说明:数据类型数据类型 函数名函数名(形参列表形参列表)double area(double x,double y,double z)double s;if(x+yz|x+zy|y+zab;s=add(a,b);coutsendl;double area(double x,y,z)double s;if(x+yz|x+zy|y+zx)return 0;s=(x+y+z)/2;s=sqrt(s*(s-x)*(s-y)*(s-z);return s;注:函数说明后无分号注:函数说明后无分号注:函数说明后无分号注:函数说明后无分号函数名:函数名:有效的有效的C+C+标识符。标识符。形式参数表:形式参数表:是用是用逗号隔开的变量说明列表逗号隔开的变量说明列表,每,每个函数参数必须同时说明个函数参数必须同时说明参数类型参数类型和和参数名参数名。注意:函数可以注意:函数可以无参数无参数,形参表为空,但,形参表为空,但函数名后的一对函数名后的一对圆括号不能省略圆括号不能省略。函数分为两类:函数分为两类:无参函数与有参函数无参函数与有参函数。关于关于return(返回返回)语句语句函数值的类型:以函数值的类型:以函数定义的类型函数定义的类型为准,为准,若不同,需将若不同,需将returnreturn语句表达式的值转换语句表达式的值转换类型。类型。在一个函数中可有多个在一个函数中可有多个returnreturn语句,但每语句,但每次被调用只能执行一个次被调用只能执行一个returnreturn语句。语句。无返回值时无返回值时voidvoid,可无,可无returnreturn语句,执行语句,执行到函数体到函数体 时返回。时返回。#includeint sushu(int n)int k,i;k=sqrt(double)n);for(i=2;i=k;i+)if(!(n%i)return 0;return 1;#include void main()for(int i=3;i100;i+=2)if(sushu(i)!=0)couti“t”;/return;作用:作用:函数体中的流程控制语句。先计算表函数体中的流程控制语句。先计算表达式的值,然后从被调函数返回到主调函达式的值,然后从被调函数返回到主调函数,表达式的值作为函数的返回值。数,表达式的值作为函数的返回值。(注意:注意:只能返回一个值只能返回一个值)语句格式:语句格式:return;return;/无值无值voidvoidreturn return 表达式;表达式;/有值有值return(return(表达式表达式);/有值有值2 函数原型(对被调函数的声明)函数原型(对被调函数的声明)v参数类型说明列表:用逗号隔开的参数类型说明,其参数个数和类型必须和参数类型说明列表:用逗号隔开的参数类型说明,其参数个数和类型必须和函数定义中的一致。也可以给出参数名,但对编译器没有什么意义。函数定义中的一致。也可以给出参数名,但对编译器没有什么意义。函数调用函数调用(使用使用)前必须先声明后调用前必须先声明后调用。函数原型的形式:函数原型的形式:数据类型数据类型数据类型数据类型 函数名函数名函数名函数名(形参类型列表形参类型列表形参类型列表形参类型列表););例:例:double area(double,double,double);v函数原型用来说明一个函数的返回值类型、参数的个数和类型。使编译器函数原型用来说明一个函数的返回值类型、参数的个数和类型。使编译器检查该函数被调用的正确与否。检查该函数被调用的正确与否。s=area(a,b,c);v调调用用户自定义函数,当对一个函数的调用出现在该函数定义之前时,必用用户自定义函数,当对一个函数的调用出现在该函数定义之前时,必须先对函数进行原型声明。当被调函数的定义写在主调函数后面时才需声须先对函数进行原型声明。当被调函数的定义写在主调函数后面时才需声明,否则可以省略函数原型说明。明,否则可以省略函数原型说明。v 调用库函数时调用库函数时,一般在文件的开头用一般在文件的开头用#include 命令将包含该函数说明的头命令将包含该函数说明的头文件加入到程序中。文件加入到程序中。double area(double x,double y,double z);求三角形面积求三角形面积#include#include/需要声明?需要声明?void main()double a,b,c,s;coutabc;s=area(a,b,c);coutarea=s endl;double area(double x,double y,double z)double s;if(x+yz|x+zy|y+zx)return 0;s=(x+y+z)/2;return sqrt(s*(s-x)*(s-y)*(s-z);#include#include/需要声明?需要声明?double area(double x,double y,double z)double s;if(x+yz|x+zy|y+zx)return 0;s=(x+y+z)/2;return sqrt(s*(s-x)*(s-y)*(s-z);void main()double a,b,c,s;coutabc;s=area(a,b,c);coutarea=s endl;原型说明放在函数被调用前原型说明放在函数被调用前double area(double,double,double);double area(double,double,double);3 函数调用函数调用函数名(实参数列表)函数名(实参数列表)函数名(实参数列表)函数名(实参数列表)For example:s=area(a,b,c);t=sum(1,2);n n实实实实参参参参表表表表可可可可包包包包含含含含多多多多个个个个参参参参数数数数,用用用用逗逗逗逗号号号号分分分分开开开开;可可可可为为为为常常常常量量量量、变变变变量量量量、函函函函数调用、表达式(先求值,再将值传递给形参)。数调用、表达式(先求值,再将值传递给形参)。数调用、表达式(先求值,再将值传递给形参)。数调用、表达式(先求值,再将值传递给形参)。n n要求实参的要求实参的要求实参的要求实参的类型和个数类型和个数类型和个数类型和个数要与形参一致。要与形参一致。要与形参一致。要与形参一致。n n可以没有参数,但圆括号一定要有,不能省略。可以没有参数,但圆括号一定要有,不能省略。可以没有参数,但圆括号一定要有,不能省略。可以没有参数,但圆括号一定要有,不能省略。n n函数调用一般用来构成表达式。函数调用一般用来构成表达式。函数调用一般用来构成表达式。函数调用一般用来构成表达式。m=power(x,7);3.1 函数的调用形式函数的调用形式void main().s=area(a,b,c);.double area(double x,double y,double z)return主调函数被调函数实参形参参数传递?3.2 函数调用过程函数调用过程1在主调函数中通过函数调用转到被调函数从而开始执行被调函数。在主调函数中通过函数调用转到被调函数从而开始执行被调函数。2执行被调函数时,遇到执行被调函数时,遇到return语句或函数体的右大括号语句或函数体的右大括号,则返回,则返回主调函数继续执行下面的语句。主调函数继续执行下面的语句。返回值?3.3 函数调用中的参数传递函数调用中的参数传递两种机制:两种机制:n传值调用:传值调用:先计算实参的值,将实参的值传递给形参。先计算实参的值,将实参的值传递给形参。(1 1)传递变量的值:)传递变量的值:(2 2)传递变量的地址:)传递变量的地址:n传引用传引用参数是主调函数与被调用函数之间交换数据的通道。参数是主调函数与被调用函数之间交换数据的通道。按照参数按照参数书写的先后次序书写的先后次序(与名字无关与名字无关),由实参向形参,由实参向形参的单向传递的单向传递要求实参和形参的类型和个数要一致,实参可为任意表要求实参和形参的类型和个数要一致,实参可为任意表达式,但要有达式,但要有确定值确定值常量常量:5变量变量:a,b,c其他表达式其他表达式:t*(t-a)*(t-b)*(t-c)地址值地址值:&a当函数当函数未被调用未被调用时,形参时,形参不占不占内存内存当函数当函数被调用时被调用时,为形参,为形参分配内存分配内存,并将实参的值传递给形参,并将实参的值传递给形参当函数当函数调用结束时调用结束时,释放释放形参所占存储形参所占存储空间空间变量值的传递:变量值的传递:先计算实参的值,将实参的值传递给形参。先计算实参的值,将实参的值传递给形参。n函数的参数传递函数的参数传递:实参将值实参将值“单向单向性性”的的“值值传递传递”给形参给形参在被调函数中对形参的值的修改不会影响到实参(在被调函数中对形参的值的修改不会影响到实参(两数交换两数交换)n形参:形参:各函数中的变量互不相关,可同名。各函数中的变量互不相关,可同名。n特点:特点:地址值的传递地址值的传递n实参可为实参可为变量的地址变量的地址,或,或数组名数组名;形参为指针变量。;形参为指针变量。求三角形面积求三角形面积n特点:特点:实参将一个地址值传递给形参时,被调用函数中对形参指针所实参将一个地址值传递给形参时,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。指向的地址中内容的任何改变都会影响到实参。1.1.传值调用传值调用求求三三角角形形面面积积#include#include double area(double x,double y,double z);void main()double a,b,c,s;coutabc;s=area(a,b,c);coutarea=sendl;double area(double x,double y,double z)double s;if(x+y=z|x+z=y|y+z=x)return 0;s=(x+y+z)/2;return sqrt(s*(s-x)*(s-y)*(s-z);Please input a,b,c=屏幕屏幕屏幕屏幕abcs3 4 53453,4,5xyzs345666area=6实参实参形参形参内存内存内存内存主调函数主调函数被调函数被调函数#includevoid swap(int x,int y);void main()int a,b;a=2;b=6;swap(a,b);cout a=a b=b;void swap(int x,int y)int t;t=x;x=y;y=t;内存内存内存内存实参实参形参形参xyb6a2266t22屏幕屏幕屏幕屏幕a=2b=6主调函数主调函数主调函数主调函数被调函数被调函数被调函数被调函数并未发生互换!并未发生互换!并未发生互换!并未发生互换!编写函数实现两数的互换:方案编写函数实现两数的互换:方案1传递变量值传递变量值编写函数实现两数的互换:方案编写函数实现两数的互换:方案2传递地址值传递地址值#includevoid swap(int*x,int*y);void main()int a,b;a=2;b=6;swap(&a,&b);cout a=a b=b;void swap(int*x,int*y)int t;t=*x;*x=*y;*y=t;主调函数主调函数被调函数被调函数实参实参形参形参xy&a&bt2屏幕屏幕屏幕屏幕a=6b=2发生互换!发生互换!发生互换!发生互换!&a&ba2b6内存内存内存内存62void sort(int x)int i,j,t;for(i=0;i9;i+)for(j=0;jxj+1)t=xj;xj=xj+1;xj+1=t;void output(int x)int i;coutThe numbers are:n;for(i=0;i10;i+)coutxit;coutn;#includevoid sort(int),output(int);void main()int a10,i;for(i=0;iai;output(a);sort(a);output(a);数组名作参数例程数组名作参数例程1-1形参:数组名形参:数组名形参:数组名形参:数组名实参:数组名实参:数组名实参:数组名实参:数组名a0ax0 x数组名作参数例程数组名作参数例程1-2形参可以包括元素个数形参可以包括元素个数形参可以包括元素个数形参可以包括元素个数void sort(int x,int n)int i,j,t;for(i=0;in-1;i+)for(j=0;jxj+1)t=xj;xj=xj+1;xj+1=t;void output(int x,int n)int i;coutThe numbers are:n;for(i=0;in;i+)coutxit;coutn;#includevoid sort(int,int),output(int,int);void main()const int SIZE=40;int aSIZE,i,n;/*INPUT*/coutn;for(i=0;iai;output(a,n);sort(a,n);output(a,n);void sort(int*px,int n)int i,j,t;for(i=0;in-1;i+)for(j=0;jpxj+1)t=pxj;pxj=pxj+1;pxj+1=t;void output(int*px,int n)int i;coutThe numbers are:n;for(i=0;in;i+)coutpxit;coutn;数组名作参数例程数组名作参数例程1-3形参为指针变量形参为指针变量形参为指针变量形参为指针变量#includevoid sort(int,int);void output(int,int);void main()const int SIZE=40;int aSIZE,i,n;/*INPUT*/coutn;for(i=0;iai;output(a,n);sort(a,n);output(a,n);a0apx0px2.2.引用传递引用传递n如果在函数中反复利用指针进行间接访问,会使程序容易产生错误且难以如果在函数中反复利用指针进行间接访问,会使程序容易产生错误且难以阅读。如果以引用作为参数,将形参作为实参的别名,则对形参的任何操阅读。如果以引用作为参数,将形参作为实参的别名,则对形参的任何操作都能改变相应的实参的数据,使函数调用显得方便、自然。作都能改变相应的实参的数据,使函数调用显得方便、自然。实参是变量名,形参是引用(不占内存空间)。此时,在被调函数实参是变量名,形参是引用(不占内存空间)。此时,在被调函数中对形参中对形参(引用引用)的任何操作都是对相应实参的操作。的任何操作都是对相应实参的操作。n特点:特点:编写函数实现两数的互换:方案编写函数实现两数的互换:方案3(引用传递引用传递)#include void swap(int&x,int&y);void main()int a,b;a=2;b=6;swap(a,b);couta=ab=b;void swap(int&x,int&y)int t;t=x;x=y;y=t;&说明形参是说明形参是说明形参是说明形参是引用,而不是引用,而不是引用,而不是引用,而不是取地址取地址取地址取地址4 函数的嵌套调用和递归调用函数的嵌套调用和递归调用n嵌套调用:嵌套调用:C+函数不能嵌套定义,即一个函数不能在函数不能嵌套定义,即一个函数不能在另一个函数体中进行定义。但在使用时,允许嵌套调用,另一个函数体中进行定义。但在使用时,允许嵌套调用,即在调用一个函数的过程中又调用另一个函数。即在调用一个函数的过程中又调用另一个函数。n递归调用:递归调用:在函数中直接或间接地调用该函数本身在函数中直接或间接地调用该函数本身#includedouble area(double,double,double);void main()double a,b,c,s;coutabc;s=area(a,b,c);cout“area=“s“n”;#include double area(double x,double y,double z)double s;if(x+yz|x+zy|y+z1n!=#includedouble fac(int n);void main()int n;double y;cinn;if(n0)coutn0,data error!;elsey=fac(n);coutn!=y;直接调用直接调用(1)写出调用终止条件)写出调用终止条件(2)写出计算公式)写出计算公式Hanoi塔塔n直接递归问题nN个盘子由A移动到B,可借助于C,大盘子不能压小盘子。n前n-1个由A到Cn第n个由A到Bn前n-1个由C到B#include void move(int n,char a,char b,char c);void main()int n;cinn;move(n,A,B,C);void move(int n,char a,char b,char c)if(n=1)coutmove from a to bendl;elsemove(n-1,a,c,b);coutmove from a to bendl;move(n-1,c,b,a);用递归方法求n!(3!)double fac(int n)f=fac(n-1)*n;return f;void main()y=fac(n);double fac(int n)f=fac(n-1)*n;return f;double fac(int n)if(n=0|n=1)f=1;return f;3211 12 26 6v执行过程执行过程5 内联函数内联函数(1 1)内联函数的意义)内联函数的意义n内联扩展(inline expansion)简称为内联(inline),内联函数也称为内嵌函数。当在一个函数的定义或声明前加上关键字inline则就把该函数定义为内联函数,它主要是解决程序的运行效率。n计算机在执行一般函数的调用时,无论该函数多么简单或复杂,都要经过参数传递、执行函数体和返回等操作,都需要一定的时间和空间开销,有时,函数本身功能简单,代码很短,但使用频率却很高,这样就使得效率降低。若把一个函数定义为内联函数后,在程序编译阶段,编译器就会把每次调用该函数的地方都直接替换为该函数体中的代码,由此省去函数的调用及相应的保存现场、参数传递和返回操作,从而加快整个程序的执行速度。(2 2)内联函数的实现:)内联函数的实现:在函数定义前面加上关键字在函数定义前面加上关键字inlineinline即可。例如:即可。例如:inlineinline int add(int x,int y,int z)int add(int x,int y,int z)return x+y+z;return x+y+z;(3 3)内联函数的原型声明)内联函数的原型声明n与其它函数一样,内联函数必须先声明后使用,如果要声明一个内联函数与其它函数一样,内联函数必须先声明后使用,如果要声明一个内联函数原型,则也必须加上声明关键字原型,则也必须加上声明关键字inlineinline。例如:。例如:inline int add(int x,int y,int z)inline int add(int x,int y,int z);/函数原型函数原型(4 4)inline inline可以同时用在函数声明和定义处,也可以只用于一处。建议将可以同时用在函数声明和定义处,也可以只用于一处。建议将内联函数的定义放在头文件中,在每个调用该内联函数的文件中都包含该内联函数的定义放在头文件中,在每个调用该内联函数的文件中都包含该头文件。头文件。(5 5)内联函数的限制:)内联函数的限制:内联函数处理方式与普通函数不同,它是将调内联函数处理方式与普通函数不同,它是将调用表达式用内联函数体来替换,若内联函数比较大,在程序中就会有多个用表达式用内联函数体来替换,若内联函数比较大,在程序中就会有多个程序备份,反而会占用更多的内存空间,这就失去了内联函数存在的实际程序备份,反而会占用更多的内存空间,这就失去了内联函数存在的实际意义。因此,意义。因此,C+C+对内联函数的定义有专门限制。对内联函数的定义有专门限制。n在内联函数内部不允许使用循环语句和开关语句,否则系统将在内联函数内部不允许使用循环语句和开关语句,否则系统将其视为普通函数。其视为普通函数。n内联函数不能是递归函数。内联函数不能是递归函数。n语句数尽可能少,一般不超过语句数尽可能少,一般不超过5 5行。行。例:用内联函数实现求某数的绝对值例:用内联函数实现求某数的绝对值#include inline int abs(int x);void main()int a,b=3,c,d=-4;a=abs(b);c=abs(d);couta=a,c=cendl;inline int abs(int x)return x0?-x:x;6 重载函数重载函数(overloading)int abs(int);/求整型数的绝对值求整型数的绝对值double fabs(double);/求双精度数的绝对值求双精度数的绝对值long labs(long);/求长整型数的绝对值求长整型数的绝对值n C+允许在同一个程序中定义多个相同名字的函数,使函数允许在同一个程序中定义多个相同名字的函数,使函数的使用更加灵活方便,即的使用更加灵活方便,即函数重载。函数重载。n 函数重载函数重载:指一组参数类型不同或参数个数不同的函数共用指一组参数类型不同或参数个数不同的函数共用同一个函数名。一个名字多个入口。同一个函数名。一个名字多个入口。n重载函数之间参数的类型或个数必须有所不同。若只有返回重载函数之间参数的类型或个数必须有所不同。若只有返回值类型不同的函数是不能重载的。值类型不同的函数是不能重载的。n编译器会将实参的类型与形参的类型一一作比较来确定应该编译器会将实参的类型与形参的类型一一作比较来确定应该调用哪个函数。若参数类型没有相同的,编译器则通过内部转调用哪个函数。若参数类型没有相同的,编译器则通过内部转换寻找类型相互匹配的函数调用。换寻找类型相互匹配的函数调用。函数名不同但功能类似,使用时不能混淆。如fabs(-12.85)写成abs(-12.85),结果则不同!例例1求两个操作数之和求两个操作数之和.#include int add(int,int);double add(double,double);void main()coutadd(5,10)endl;coutadd(5.0,10.5)endl;int add(int x,int y)return x+y;double add(double a,double b)return a+b;例例2 求几个整数中的最小值求几个整数中的最小值.#include int min(int,int);int min(int,int,int);int min(int,int,int,int);void main()coutmin(5,10,15,2)endl;coutmin(-2,1,-9)endl;int min(int a,int b)return ab?a:b;int min(int a,int b,int c)int t=min(a,b);return tc?t:c;int min(int a,int b,int c,int d)int t=min(a,b,c);return td?t:d;7 带默认参数的函数带默认参数的函数n 默认参数:在定义函数时,为形参预先定义缺省的参数值。默认参数:在定义函数时,为形参预先定义缺省的参数值。当函数调用时,如果给出实参,则将实参的值传给形参;如当函数调用时,如果给出实参,则将实参的值传给形参;如果没有给出实参,则形参使用预先给定的缺省值。果没有给出实参,则形参使用预先给定的缺省值。例如:例如:这样调用时可以指定或省略参数。例如:delay(3000);delay();void delay(int loops=1000)/函数定义函数定义 if(loops=0)return;for(int i=0;iloops;i+);在调用有默认参数的函数时,实参的个数可以与形参不同,在调用有默认参数的函数时,实参的个数可以与形参不同,从而使函数的调用更加灵活。从而使函数的调用更加灵活。n多个形参,可以使每个形参有一个默认值,也可以只对一部分形多个形参,可以使每个形参有一个默认值,也可以只对一部分形参指定默认值,另一部分形参不指定默认值参指定默认值,另一部分形参不指定默认值。如:如:double volume(double h,double r=3.2);n调用时可采用:调用时可采用:volume(45.6)volume(32.5,10.4)n实参与形参的结合是从左至右顺序进行的,因此指定默认值的参实参与形参的结合是从左至右顺序进行的,因此指定默认值的参数必须放在形参列表中的最右端,否则出错。数必须放在形参列表中的最右端,否则出错。例如:例如:void func(int a=1,int b,int c=3,int d=4);/错错 void func(int a,int b=2,int c=3,int d=4);/正确正确n调用时可采用如下形式:调用时可采用如下形式:nfunc(2)nfunc(2,5)nfunc(2,3,5)nfunc(1,8,7,3)n错误形式为:错误形式为:nfunc()nfunc(2,1,6)使用默认参数时注意:使用默认参数时注意:n如如果果函函数数的的定定义义在在函函数数调调用用之之前前,则则应应在在函函数数定定义义中中给给出出默默认认值值。如如果果函函数数的的定定义义在在函函数数调调用用之之后后,则则在在函函数数调调用用之之前前需需要要有有函函数数原原型型声声明明,此此时时必必须须给给出出默默认认值值,而而在在函函数数定定义义时时可可以以不不给给出出默默认认值值。(要要在在函函数数调调用用之之前将默认值的信息通知编译系统。前将默认值的信息通知编译系统。)n如如果果在在声声明明函函数数原原型型时时已已对对形形参参给给出出了了默默认认值值,而而在在定定义义函函数数时时又又对对形形参参给出默认值,编译系统会给出给出默认值,编译系统会给出“重复指定默认值重复指定默认值”错误信息。错误信息。n一一个个函函数数不不能能既既作作为为重重载载函函数数,又又作作为为有有默默认认参参数数的的函函数数。因因为为当当调调用用函函数时,出现二义性,系统无法区分。数时,出现二义性,系统无法区分。n利用默认参数可将若干重载函数合成为一个。例如三个重载函数:void point(int,int);void point(int a)return point(a,4);void point()return point(3,4);n可以合成为下面带有默认参数的函数 void point(int=3,int=4);/函数原型,可省略形式参数名。n下面调用都是合法的。point();/调用point(3,4),等于调用上面第三个函数 point(6);/调用point(6,4),等于调用上面第二个函数 point(7,8);/调用 point(7,8),等于调用上面第一个函数8 作用域与生存期作用域与生存期n作用域是一个标识符在程序正文中的有效范围,生存期是指变作用域是一个标识符在程序正文中的有效范围,生存期是指变量或对象从诞生到结束的这段时间量或对象从诞生到结束的这段时间n作用域作用域n函数原型作用域函数原型作用域n块作用域块作用域:又称局部作用域又称局部作用域n类作用域类作用域n文件作用域文件作用域n生存期生存期n与存储区域关系密切,一般将存储区域分为:与存储区域关系密切,一般将存储区域分为:nCode area 代码区,存放程序代码代码区,存放程序代码nData area数据区,静态生存期数据区,静态生存期nStack area栈区,局部生存期栈区,局部生存期nHeap area堆区,动态生存期堆区,动态生存期8.1 作用域作用域n函数原型作用域函数原型作用域:+程序中最小的作用域,函数原型的声程序中最小的作用域,函数原型的声明中包含的参数如:明中包含的参数如:double area(double a,double b,double c);n块作用域块作用域:又称局部作用域又称局部作用域n当标识符的声明出现在由当标识符的声明出现在由一对所括起来的程序一对所括起来的程序块内时,则此块中声明的块内时,则此块中声明的标识符的作用域从声明处标识符的作用域从声明处开始,一直到块结束的花开始,一直到块结束的花括号为止括号为止includevoid fun1();void main()int n=0;for(int i=0;i5;i+)int m;if(i%2)n+;m=n/2;/error!fun1();n=i;void fun1()cout“i=“iendl;/error!n文件作用域n即标识符是在所有函数定义之外声明的,其作用域从声明即标识符是在所有函数定义之外声明的,其作用域从声明点开始,一直延伸至文件尾一般情况下,程序中声明的点开始,一直延伸至文件尾一般情况下,程序中声明的全局变量都具有文件作用域,它们在整个文件中都有效全局变量都具有文件作用域,它们在整个文件中都有效#includeint k;void main()k=5;fun();k+;cout=0&a!=0)t=sqrt(t);x1=(-b+t)/(2*a);x2=(-b-t)/(2*a);return 1;return 0;#include#include int root(double,double,double);double x1,x2;void main()double a,b,c;coutabc;if(root(a,b,c)coutx1tx2n;F全局变量全局变量F局部变量局部变量int x,y,z;double f1(int a)int b,c;char f2(int x,int y)int i,j;.void main()int a,b,c;x=a+b+c;.F全局变量全局变量F局部变量局部变量全局变量全局变量x,y,z的有效范围的有效范围(作用域作用域作用域作用域)a,b,c的有的有效范围效范围x,y,i,j的的有效范围有效范围a,b,c的有的有效范围效范围 当局部变量名与全局变量名相同时,在局部变量的作用域中,当局部变量名与全局变量名相同时,在局部变量的作用域中,局部变量起作用,全局变量不起作用。局部变量起作用,全局变量不起作用。#includeint x=1,y=2,z=3;fun1(int x)int z;z=x+y;y=1;coutxtytzn;return z;void main()int a=10;x=fun1(a);coutxtytzn;局部变量与全局变量同名局部变量与全局变量同名fun1(10)10 x10+2z1y输出结果:输出结果:x=10,y=1,z=12x=12,y=1,z=3作用域运算符作用域运算符:n局部变量与全局变量同名时,局部变量将屏蔽全局变量,若要局部变量与全局变量同名时,局部变量将屏蔽全局变量,若要访问全局变量,可以使用作用域运算符访问全局变量,可以使用作用域运算符:,它能指定所需要的,它能指定所需要的作用域。作用域。#includeint x=1;void main()int x=10;cout xendl:x;输出:10 1程序中的各种变量都有一个在需要时被创建,而在不需要时被删除的过程。在创建和删除之间所经过的时间就被称为生命期。C+程序在用户区内存分配示意图程序在用户区内存分配示意图 程序代码区静态存储区 动态存储区 8.3 变量的存储类型变量的存储类型1、自动存储类型、自动存储类型auto自动变量存储在动态存储区;当函数被调用时随机分配存储自动变量存储在动态存储区;当函数被调用时随机分配存储空间,返回时释放空间,返回时释放(其初始化相当于一次赋值,函数每次被其初始化相当于一次赋值,函数每次被调用时都执行调用时都执行);是局部变量的缺省存储类型。;是局部变量的缺省存储类型。2、静态存储类型、静态存储类型static静态变量存储在静态存储区;在执行程序的整个过程中,不静态变量存储在静态存储区;在执行程序的整个过程中,不管函数是否被调用,都占据其存储空间;管函数是否被调用,都占据其存储空间;只初始化一次只初始化一次3、外部存储类型、外部存储类型extern全局变量的缺省类型为全局变量的缺省类型为extern类型类型4、寄存器存储类型、寄存器存储类型register寄存器变量存储在寄存器中寄存器变量存储在寄存器中(CPU中),快!因寄存器数量有中),快!因寄存器数量有限,该种变量个数不能多。限,该种变量个数不能多。局部变量的存储类别局部变量的存储类别n自动变量自动变量 auto 每次调用函数时才在动态存储区为其随机分配存储空间,每次调用函数时才在动态存储区为其随机分配存储空间,返回时释放;其初始化相当于一次赋值,函数每次被调用返回时释放;其初始化相当于一次赋值,函数每次被调用时都执行;是局部变量的缺省存储类型。时都执行;是局部变量的缺省存储类型。n静态局部变量静态局部变量 static 静态变量存储在静态动态存储区;在执行程序的整个过程中,静态变量存储在静态动态存储区;在执行程序的整个过程中,不管函数是否被调用,静态变量在静态存储区始终占据其不管函数是否被调用,静态变量在静态存储区始终占据其存储空间;存储空间;必须进行初始化,且只初始化一次必须进行初始化,且只初始化一次,在编译时,在编译时进行进行n寄存器变量寄存器变量 register局部变量的自动和静态存储类型举例局部变量的自动和静态存储类型举例(1)#include void fun1(int x)static int y;int z=10;x=x+y;y=x+z;coutxtytzn;void main()fun1(1);fun1(1);静态变量只静态变量只初始化一次初始化一次,自动初始化自动初始化为为011110122210局部变量的自动和静态存储类型举例局部变量的自动和静态存储类型举例(2)#include void fun(int k)int n=1;static int m=1;n+=k;m+=k;coutntmendl;void main()for(int i=1;i3;i+)fun(8);静态变量静态变量只初始化一次只初始化一次全局变量的存储类别全局变量的存储类别n全局变量存储在静态存储区(改变作用域改变作用域)n内部的 static静态外部变量作用域为本程序文件,其它程序静态外部变量作用域为本程序文件,其它程序文件不能使用文件不能使用n外部的 extern外部变量除本程序文件使用外,也可被其它程外部变量除本程序文件使用外,也可被其它程序文件使用,此时要用序文件使用,此时要用extern在文件中进行声在文件中进行声明。明。指针与函数n指针可作函数参数,从而方便地实现地址传递。函数指针可作函数参数,从而方便地实现地址传递。函数可以返回指针,指针也可以指向函数。可以返回指针,指针也可以指向函数。1、指针作为函数参数n如如果果参参数数是是指指针针,则则在在被被调调函函数数中中,可可通通过过形形参参指指针针指向的地址中内容的改变而影响到实参。指向的地址中内容的改变而影响到实参。n虽虽然然用用指指针针作作函函数数的的参参数数可可以以使使得得形形参参的的改改变变对对相相应应的的实实参参有有效效。但但是是,如如果果在在函函数数中中反反复复使使用用指指针针进进行行间间接接访访问问,会会影影响响程程序序的的可可读读性性且且容容易易产产生生错错误误,因因此此在在C+语语言言中中扩扩充充了了引引用用的的概概念念,这这样样既既可可以以实实现现指针所带来的功能,又使程序清晰易读。指针所带来的功能,又使程序清晰易读。2、指针函数、指针函数n指针作为函数的返回值。当一个函数的返回值是指针指针作为函数的返回值。当一个函数的返回值是指针类型时,这个函数就是指针函数。类型时,这个函数就是指针函数。n非指针型函数值只能返回一个数据。当需要从被调函非指针型函数值只能返回一个数据。当需要从被调函数返回一批数据到主调函数时,可通过指针型函数来数返回一批数据到主调函数时,可通过指针型函数来解决。指针型函数在调用后返回一个指针,通过指针解决。指针型函数在调用后返回一个指针,通过指针中存储的地址值,主调函数就能访问该地址中存放的中存储的地址值,主调函数就能访问该地址中存放的数据,并通过指针算术运算访问这个地址的前、后内数据,并通过指针算术运算访问这个地址的前、后内存中的值。因此,通过对空间的有效组织(如数组、存中的值。因此,通过对空间的有效组织(如数组、字符串等能前后顺序存放多个数据的类型),字符串等能前后顺序存放多个数据的类型),从而可从而可以返回大量的数据以返回大量的数据。n数据类型数据类型*函数名(参数表)函数名(参数表)n如:如:int*fun(a,b)#includeint*f(int n);void main()int n,*p;cinn;p=f(n);for(int i=0;in;i+)coutpit;coutendl;delete p;int*f(int n)int*p;p=new int n;for(int i=0;ipi;return p;若干学生若干学生4门课成绩,输入学生序号后,输出该学生的全部成绩。门课成绩,输入学生序号后,输出该学生的全部成绩。#include iostream.hdouble*search(double(*pointer)4,int n);void main()double score4=60,70,80,90,56,89,67,88,34,78,90,66;double*p;int i,m;coutm;coutThe scores of Nom:;p=search(score,m);for(i=0;i4;i+)cout*(p+i);coutendl;double*search(double(*pointer)4,int n)double*pt;pt=*(pointer+n);return(pt);3、函数指针、函数指针n1)函数指针就是指向函数的指针。函数指针就是指向函数的指针。定义函数指针定义函数指针的语法格式为:的语法格式为:数据类型数据类型(*函数指针名)(参数表);函数指针名)(参数表);数据类型是函数指针所指函数返回值类型,参数表为该函数的形参数据类型是函数指针所指函数返回值类型,参数表为该函数的形参例如:例如:int(*p)(int,int);/函数指针函数指针p指向一个返回整型值,有两个整型参数的函数。指向一个返回整型值,有两个整型参数的函数。n2)函函数数指指针针的的赋赋值值,使使它它指指向向一一个个函函数数的的入入口口地地址址/首首地地址址。由由于于函函数数名名是是函函数数在在内内存存中中的的首首地地址址,因因此此可可以以赋赋给给函函数数指指针针变量。则赋值格式为:变量。则赋值格式为:函数指针名函数指针名=函数名;函数名;例:例:p=func1;或或p=&func1;/正确正确n其其中中的的函函数数名名所所代代表表的的函函数数必必须须是是一一个个已已经经定定义义过过的的,和和函函数数指指针针具具有有相相同同返返回回类类型型的的函函数数。并并且且只只需需写写函函数数名名而而不不要要写写参参数,例如不要写成:数,例如不要写成:p=func1(a,b);/错误错误3、函数指针、函数指针n3)利用函数指针调用函数利用函数指针调用函数,当函数指针指向某函数后,当函数指针指向某函数后(先赋值,再调用先赋值,再调用),可利用该指针调用函数:,可利用该指针调用函数:(*指针变量)(实参表列)指针变量)(实参表列)例如:例如:(*p)(a,b),它相当于,它相当于funl(a,b)。n注:函数指针的运算是无意义的。因为指针指向函数注:函数指针的运算是无意义的。因为指针指向函数的首地址,而被调函数的执行必须从首地址开始。若的首地址,而被调函数的执行必须从首地址开始。若进行指针运算,程序的执行就不是从函数的开始位置进行指针运算,程序的执行就不是从函数的开始位置执行,这就会造成错误。执行,这就会造成错误。n调调用用process函函数数时时,每每次次实实现现不不同同的的功功能能。输输入入a和和b两两个个数数,第第一一次次调调用用process时时找找出出a和和b中中大大者者,第第二二次次找找出其中小者,第三次求出其中小者,第三次求a与与b之和。之和。#include int max(int,int);int min(int,int);int add(int,int);process(int,int,int(*fun)(int,int);void main()int a,b;coutab;coutmax=;process(a,b,max);coutmin=;process(a,b,min);couty)z=x;elsez=y;return(z);min(int x,int y)int z;if(xy)z=x;elsez=y;return(z);add(int x,int y)int z;z=x+y;return(z);process(int x,int y,int(*fun)(int,int)int result;result=(*fun)(x,y);coutresultendl;p经常不断地学习,你就什么都知道。你知道得越多,你就越有力量pStudyConstantly,AndYouWillKnowEverything.TheMoreYouKnow,TheMorePowerfulYouWillBe写在最后感谢聆听不足之处请大家批评指导Please Criticize And Guide The Shortcomings结束语讲师:XXXXXX XX年XX月XX日
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!