资源预览内容
第1页 / 共64页
第2页 / 共64页
第3页 / 共64页
第4页 / 共64页
第5页 / 共64页
第6页 / 共64页
第7页 / 共64页
第8页 / 共64页
第9页 / 共64页
第10页 / 共64页
亲,该文档总共64页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
四讲函数及变量的作用域Stillwatersrundeep.流静水深流静水深,人静心深人静心深Wherethereislife,thereishope。有生命必有希望。有生命必有希望修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2 2函数的定义和说明函数的定义和说明函数的定义和说明函数的定义和说明函数的调用函数的调用函数的调用函数的调用函数的参数函数的参数函数的参数函数的参数内联函数内联函数内联函数内联函数函数重载函数重载函数重载函数重载函数的嵌套调用和递归调用函数的嵌套调用和递归调用函数的嵌套调用和递归调用函数的嵌套调用和递归调用作用域作用域作用域作用域C+C+的系统函数的系统函数的系统函数的系统函数主要内容修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域3 34.1 4.1 函数的定义和说明函数的定义和说明函数的定义格式函数的定义格式函数的定义格式函数的定义格式函数的说明方法函数的说明方法函数的说明方法函数的说明方法修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4 4一个一个C+C+函数由函数由函数头函数头与与函数体函数体两部分组成。两部分组成。形式如下:形式如下:函数类型函数类型 函数名(形式参数类型函数名(形式参数类型 形式参数名,形式参数名,) 函数体函数体 如:如: int fun1(char c,float f)int fun1(char c,float f)int fun1(char c,float f)int fun1(char c,float f) int m=1; int m=1; int m=1; int m=1; m+=c+f; m+=c+f; m+=c+f; m+=c+f; return m;return m;return m;return m; 函数的定义格式函数的定义格式即函数返回值的类型。无返回值为void类型语句序列。描述了实现功能的过程,并一般要最后执行一条return语句。可包含多个形式参数。定义了函数将从调用函数中接收多少个数据及其类型修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5 5返回语句的形式为:返回语句的形式为: return return 表达式;表达式;这时这时表达式的结果表达式的结果就是函数的返回值,也称函数值。就是函数的返回值,也称函数值。即返回的不是函数本身,而是一个值。即返回的不是函数本身,而是一个值。若函数所执行的功能不需要返回数据,则可缺省若函数所执行的功能不需要返回数据,则可缺省 returnreturn语句。语句。如:如: void spc (int n) void spc (int n) for (int I=0; In; I+) for (int I=0; In; I+) cout*; cout*; 注意:注意:函数类型为函数类型为voidvoid,若无默认为,若无默认为intint。 C+ C+不允许函数定义嵌套不允许函数定义嵌套。 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域6 6函数的说明方法函数的说明方法其形式为:其形式为:函数类型函数名(参数类型表);函数类型函数名(参数类型表);如:如: int absolute_value ( int ,double);int absolute_value ( int ,double);int absolute_value ( int ,double);int absolute_value ( int ,double);要要求求在在调调用用函函数数前前让让编编译译器器知知道道其其函函数数原原型型,以以便便编编译译器器利利用用函函数数原原型型提提供供的的信信息息来来检检查查调调用用的的合合法法性性,强强制制参参数数为为适适当当类类型型,保保证证参参数数的的正正确传递。确传递。而编译器获得函数原型有两种情况:而编译器获得函数原型有两种情况:()当当函函数数定定义义在在调调用用之之前前时时,则则从从定定义义中中抽抽取取函数原型。函数原型。()当当函函数数定定义义在在调调用用之之后后时时,则则程程序序员员须须在在调调用用之之前前用用函函数数原原型型对对函函数数进进行行声声明明,让让编编译译器器获获得函数原型。得函数原型。即所有参数的数据类型修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域7 7对对于于标标准准库库函函数数的的函函数数原原型型都都在在头头文文件件中中提提供供了,程序可用了,程序可用#include#include命令包含进来即可;命令包含进来即可;注注意意:函函数数原原型型和和函函数数定定义义在在返返回回类类型型、函函数数名和参数表上名和参数表上必须完全一致必须完全一致,否则编译错误。,否则编译错误。注注 意意修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域8 8#include void f1 ( ) ; /函数说明void f2 ( ) ;void main( ) f1( ); /函数调用 f2( ); void f1( ) /函数定义 cout Function f1.n;f2( );void f2( ) cout Function f2 .n;main()f1()f2()修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域9 9修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域10104.2 4.2 函数的调用函数的调用函数的值和类型函数的值和类型函数的值和类型函数的值和类型函数的传值调用函数的传值调用函数的传值调用函数的传值调用函数的引用调用函数的引用调用函数的引用调用函数的引用调用修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1111函数的值和类型函数的值和类型函数调用通过调用表达式进行。函数调用通过调用表达式进行。表达式形式为:表达式形式为:函数名(实参表列)函数名(实参表列)函数调用过程函数调用过程是:是:为形参及函数体中的变量分配存储空间;为形参及函数体中的变量分配存储空间;用实参向形参传递数据;用实参向形参传递数据;中断现行(调用)函数,将控制转交给被调用函数执行。中断现行(调用)函数,将控制转交给被调用函数执行。函数调用后的返回过程函数调用后的返回过程是:是:先计算出返回语句中先计算出返回语句中 的值的值若表达式值的类型与函数类型不一致,则强制转换。若表达式值的类型与函数类型不一致,则强制转换。将计算出的表达式值返回给调用函数作为返回值。将计算出的表达式值返回给调用函数作为返回值。将控制由被调用函数转向调用函数,执行后面的语句。将控制由被调用函数转向调用函数,执行后面的语句。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1212如:如: #include#include int lmax(int,int); / int lmax(int,int); /函数声明函数声明 void main( ) void main( ) int limit=32; char ch=A; long mval; int limit=32; char ch=A; long mval; mval=lmax( mval=lmax(limit,chlimit,ch); /); /调用表达式调用表达式 coutmvalendl;coutmvalb?a:b); return (ab?a:b); 实参的个数、类型及顺序要与形参保持一致形式参数实际参数修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1313说明:说明:(1 1)实实参参在在进进行行函函数数调调用用时时,必必须须具具有有确确定定的的值,以便把这些值传送给形参。值,以便把这些值传送给形参。(2 2)形形参参变变量量只只有有在在被被调调用用时时,才才分分配配内内存存单单元;调用结束时,即刻释放所分配的内存单元。元;调用结束时,即刻释放所分配的内存单元。因因此此,形形参参只只有有在在该该函函数数内内有有效效。调调用用结结束束,返回调用函数后,则不能再使用该形参变量。返回调用函数后,则不能再使用该形参变量。(3 3)实实参参对对形形参参的的数数据据传传送送是是单单向向的的,即即只只能能把把实实参参的的值值传传送送给给形形参参,而而不不能能把把形形参参的的值值反反向向地地传送给实参。传送给实参。(4 4)实实参参和和形形参参占占用用不不同同的的内内存存单单元元,即即使使同同名也互不影响。名也互不影响。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1414函数的传值调用函数的传值调用C+C+中变量值有两种:变量本身值和变量地址值。而形中变量值有两种:变量本身值和变量地址值。而形参的类型也就分为两种:一般类型和指针类型。参的类型也就分为两种:一般类型和指针类型。则传值调用的方式也有两种:则传值调用的方式也有两种:传值调用和传址调用传值调用和传址调用有时也称:直接调用与间接调用直接调用与间接调用1 1 1 1、传值调用的实现机制和特点、传值调用的实现机制和特点、传值调用的实现机制和特点、传值调用的实现机制和特点实现机制是:调用函数中的数据只是在调用之初通过实实现机制是:调用函数中的数据只是在调用之初通过实参向形参参向形参传递传递,之后,之后各占有各占有不同的空间,并且不同的空间,并且不再不再发生发生联系,联系,互不干扰互不干扰。特点是:特点是:形参值的改变不影响实参形参值的改变不影响实参。实参本身的值在调用前后和调用过程中都不发生变化。实参本身的值在调用前后和调用过程中都不发生变化。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1515函数函数swapswap本想实现本想实现交换交换a a和和b b值值的功能,但调用结果却不的功能,但调用结果却不如意。原因就在于这种调用是一种如意。原因就在于这种调用是一种值调用值调用。例:例:#include #include void swap(void swap(int,intint,int); ); void main( )void main( ) int int a=3,b=5; a=3,b=5; coutbefore coutbefore swap swap :a=a,b=bendl;:a=a,b=bendl; swap( swap(a,ba,b);); coutafter swap :a=a,b=bendl; coutafter swap :a=a,b=bendl; void swap(void swap(int a,int bint a,int b) ) int temp; int temp; temp=a; a=b; b=temp;temp=a; a=b; b=temp; coutin coutin swap swap :a=a,b=bendl; :a=a,b=bendl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1616调用swap时,内存单元分配情况:353ababtemp 实参 形参3535实参形参35过程调用中35过程调用后temp=a; a=b; b=temp;修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1717实现机制是:实参为某实现机制是:实参为某变量地址值变量地址值,形参为,形参为指指针类型针类型。在调用时,将。在调用时,将地址值赋给地址值赋给形参,使形参指形参,使形参指针针指向指向该变量。则以后可直接通过形参指针来该变量。则以后可直接通过形参指针来访问访问该变量。该变量。特点是:特点是:可通过改变形参所指向的变量值来影可通过改变形参所指向的变量值来影响实参所对应的变量值响实参所对应的变量值。 2 2 2 2、传址调用的实现机制和特点、传址调用的实现机制和特点、传址调用的实现机制和特点、传址调用的实现机制和特点修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1818函数函数swapswap实现了实现了交换交换a a和和b b值值的功能。原因就在于这种调用是的功能。原因就在于这种调用是一种一种传址调用传址调用。例:例:#include #include void swap( void swap(int *,int *int *,int *);); void main( ) void main( ) int int a=3,b=5; a=3,b=5; coutbefore swap :a=a,b=bendl; coutbefore swap :a=a,b=bendl; swap( swap(& &a,&ba,&b); /); /实参为变量地址 coutafter swap :a=a,b=bendl; coutafter swap :a=a,b=bendl; void swap(void swap(int * a,int *bint * a,int *b) /) /形参为指针类型 int temp; int temp; temp=*a; temp=*a; *a=*b; *a=*b; *b=temp; *b=temp; /注意引用方式 coutin swap :a=a,b=bendl; coutin swap :a=a,b=bendl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域1919调用swap时,内存单元分配情况:35353过程调用后 形参ababtemp 实参3510012008实参形参2008100120081001过程调用中35temp=*a; *a=*b; *b=temp;修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2020函数的引用调用函数的引用调用使用使用引用引用作为函数作为函数形参形参时,调用函数的时,调用函数的实参实参要要用用变量名变量名。将实参变量名赋给形参的引用,则在被。将实参变量名赋给形参的引用,则在被调函数中,对引用的操作,调函数中,对引用的操作,实质实质就是直接通过引用就是直接通过引用来操作实参的变量值。来操作实参的变量值。显显然然,引引用用传传递递方方式式具具有有传传址址调调用用的的效效果果,又又有传值调用的语法简单性和可读性。有传值调用的语法简单性和可读性。注意:注意:若若只只从从调调用用语语句句观观察察,是是无无法法区区别别采采用用的的是是传传值调用还是引用调用。值调用还是引用调用。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2121函数函数swapswap实现了实现了交换交换a a和和b b值值的功能。这里调用是采的功能。这里调用是采用了用了引用调用引用调用。例:例:#include void swap(int &,int &); void main( ) int a=3,b=5; coutbefore swap :a=a,b=bendl; swap(a,b); /实参为变量名 coutafter swap :a=a,b=bendl; void swap(int & a,int &b) /形参为引用类型 int temp; temp=a; a=b; b=temp; /注意区别 coutin swap :a=a,b=bendl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2222调用swap时,内存单元分配情况:35353过程调用后 形参ababtemp 实参35实参形参20081001过程调用中35temp=a; a=b; b=temp;修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域23234.3 4.3 函数的参数函数的参数函数参数的求值顺序函数参数的求值顺序函数参数的求值顺序函数参数的求值顺序设置函数参数的默认值设置函数参数的默认值设置函数参数的默认值设置函数参数的默认值使用数组作函数参数使用数组作函数参数使用数组作函数参数使用数组作函数参数修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2424函数参数的求值顺序函数参数的求值顺序由于使用不同求值顺序的编译器而造成二义性。由于使用不同求值顺序的编译器而造成二义性。 #include #include int int add(int add(int x,int x,int y); y); /函函数数声声明明 void main( ) void main( ) int a=4,b=6; int a=4,b=6; int int z=add(z=add(+a,a+b+a,a+b); ); /从从左左至至右右为为5 115 11 coutzendl; coutzendl; /从从右右至至左左为为5 105 10 int add(int x,int y) int add(int x,int y) /函数定义(实现)函数定义(实现) return x+y; return x+y; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2525设置函数参数的默认值设置函数参数的默认值在函数说明语句中预先初始化一些参数的值,从而使在函数说明语句中预先初始化一些参数的值,从而使调用语句中相应的参数可以缺省。调用语句中相应的参数可以缺省。如:如: int max(int, int, int=-32768);int max(int, int, int=-32768);int max(int, int, int=-32768);int max(int, int, int=-32768);则在函数调用时可以不给最后一个参数传递值,而采则在函数调用时可以不给最后一个参数传递值,而采用缺省值。如:用缺省值。如: max(i1,i2);max(i1,i2);max(i1,i2);max(i1,i2); / / 参数缺省调用参数缺省调用 max(i1,i2,i3);max(i1,i2,i3);max(i1,i2,i3);max(i1,i2,i3); / /正常调用正常调用允许函数默认参数值,是为了让编程简单。允许函数默认参数值,是为了让编程简单。设置函数参数的默认值是按设置函数参数的默认值是按从右至左的方式从右至左的方式当又有声明又有定义时,定义中不允许默认参数。若当又有声明又有定义时,定义中不允许默认参数。若只有定义,则默认参数才可出现在函数定义中。只有定义,则默认参数才可出现在函数定义中。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2626注意:注意:若一个函数中有多个默认参数,则参数若一个函数中有多个默认参数,则参数缺省按缺省按从后向前从后向前的顺序进行,的顺序进行,如:如:void fun(int a=3,int,char c=a);void fun(int a=3,int,char c=a);void fun(int a=3,int,char c=a);void fun(int a=3,int,char c=a); /errorerrorerrorerror 当调用函数时,也只能从右向左匹配参数。当调用函数时,也只能从右向左匹配参数。如:如:声明函数为:声明函数为:void func(int a,int b=2,int c=3void func(int a,int b=2,int c=3void func(int a,int b=2,int c=3void func(int a,int b=2,int c=3,int int int int d=5);d=5);d=5);d=5);则调用方法:则调用方法:func(2,15, ,3);func(2,15, ,3);func(2,15, ,3);func(2,15, ,3); / / errorerrorerrorerror修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2727使用数组作函数参数使用数组作函数参数1 1 1 1、形参和实参都用数组、形参和实参都用数组、形参和实参都用数组、形参和实参都用数组 这种调用的机制是这种调用的机制是: :形参和实参共用内存中的同形参和实参共用内存中的同一个数组空间一个数组空间。因此,在被调用函数中改变了数组。因此,在被调用函数中改变了数组中某个元素的值,对调用函数该数组的该元素值也中某个元素的值,对调用函数该数组的该元素值也被改变,因为是被改变,因为是共用同一个数组。共用同一个数组。#include #include int a8=1,3,5,7,9,11,13;int a8=1,3,5,7,9,11,13;void fun(void fun(int b ,int nint b ,int n) ) for (int I=0;In-1;I+) for (int I=0;In-1;I+) b7+=bI; b7+=bI; void main( )void main( ) int m=8; fun( int m=8; fun(a,ma,m); ); couta7endl; couta7endl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域2828#include void invert(char b,int n);void main() char s60; int n; couts; cout字符串原始顺序:sendl; n=strlen(s); invert(s,n); cout字符串反转后的顺序:sendl;void invert(char b,int n) for(int i=0;in/2;i+) char c=bi; bi=bn-1-i; bn-1-i=c; S0S1S2S3S4输入一字符串个数,反序存放并输出输入一字符串个数,反序存放并输出不能写成invert(sn,n)有问题吗?修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域29292 2 2 2、形参和实参都用对应数组的指针、形参和实参都用对应数组的指针、形参和实参都用对应数组的指针、形参和实参都用对应数组的指针实际,也可一个使用指针,另一个使用数组。实际,也可一个使用指针,另一个使用数组。在使用指针时,可以直接用数组名,也可用另外定在使用指针时,可以直接用数组名,也可用另外定义的指向数组的指针。义的指向数组的指针。#include #include int a8=1,3,5,7,9,11,13;int a8=1,3,5,7,9,11,13;void fun(void fun(int *pa,int nint *pa,int n) /) /函数声明与定义函数声明与定义函数声明与定义函数声明与定义 for (int I=0;In-1;I+) for (int I=0;In-1;I+) *(pa+7)+=*(pa+I)*(pa+7)+=*(pa+I); ; void main( )void main( ) int m=8; fun( int m=8; fun(a,ma,m); ); couta7endl; couta7endl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域3030#include void invert(char *b,int n);void main() char s60; int n;/char *p=s; couts; cout字符串原始顺序:sendl; n=strlen(s); invert(s,n);/ invert(p,n); cout字符串反转后的顺序:sendl;void invert(char *b,int n) for(int i=0;in/2;i+) char c=*(b+i); *(b+i)=*(b+n-1-i); *(b+n-1-i)=c; 输入一字符串个数,反序存放并输出输入一字符串个数,反序存放并输出修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域31313 3 3 3、形参用引用实参用数组名、形参用引用实参用数组名、形参用引用实参用数组名、形参用引用实参用数组名其中要先用类型定义语句定义一个其中要先用类型定义语句定义一个intintintint型的数组类型。型的数组类型。typedef int aref8;typedef int aref8;typedef int aref8;typedef int aref8;/类型定义类型定义类型定义类型定义int a8=1,3,5,7,9,11,13;int a8=1,3,5,7,9,11,13;int a8=1,3,5,7,9,11,13;int a8=1,3,5,7,9,11,13;void fun(void fun(void fun(void fun(aref &b,int naref &b,int naref &b,int naref &b,int n) ) ) ) for (int I=0;In-1;I+) for (int I=0;In-1;I+) for (int I=0;In-1;I+) for (int I=0;In-1;I+) b7+=bI; b7+=bI; b7+=bI; b7+=bI; void main( )void main( )void main( )void main( ) int m=8; fun( int m=8; fun( int m=8; fun( int m=8; fun(a,ma,ma,ma,m);););); couta7endl; couta7endl; couta7endl; couta7endl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域3232#include typedef char arr60; /先用类型定义一个char型的数组类型void invert(arrarr &b,int n);void main() char s60; int n,*p=s; coutp; cout字符串原始顺序:sendl; n=strlen(s); invert(s,n); cout字符串反转后的顺序:sendl;void invert(arr &b,int n) for(int i=0;in/2;i+) char c=bi; bi=bn-1-i; bn-1-i=c; 输入一字符串个数,反序存放并输出输入一字符串个数,反序存放并输出修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域33334.4 4.4 内联函数内联函数引入的原因引入的原因引入的原因引入的原因定义方法定义方法定义方法定义方法注意事项注意事项注意事项注意事项修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域3434引入原因引入原因目的是为了解决程序中函数调用的目的是为了解决程序中函数调用的效率效率问题。问题。函函数数调调用用时时需需要要建建立立栈栈内内存存环环境境,进进行行参参数数传传递递,并并产产生生程程序序执执行行转转移移,则则都都要要有有时时间间和和空空间间的的代价。代价。而而有有时时一一些些函函数数代代码码很很短短(行行),却却有有高使用频率,造成处理现场的开销巨增。高使用频率,造成处理现场的开销巨增。这这时时若若将将函函数数体体嵌嵌入入函函数数调调用用处处,则则可可避避免免每每次调用函数的开销。大大提高效率。次调用函数的开销。大大提高效率。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域3535通过将该函数声明为通过将该函数声明为inlineinlineinlineinline来实现。来实现。即在函数声明和定义中用即在函数声明和定义中用inlineinlineinlineinline来修饰。来修饰。如:如:inline inline inline inline int isnumber(char); int isnumber(char); int isnumber(char); int isnumber(char); void main( )void main( )void main( )void main( ) char ch; char ch; char ch; char ch; for (int I=1; I=10; I+) for (int I=1; I=10; I+) for (int I=1; I=10; I+) for (int I=1; Ich; cinch; cinch; cinch; int p=isnumber(ch); int p=isnumber(ch); int p=isnumber(ch); int p=isnumber(ch); coutpendl; coutpendl; coutpendl; coutp=0&ch=0&ch=0&ch=0&chy) ? x: y); double max (double x , double y) return ( (xy) ?x: y); #include void main( ) coutmax(10,20)endl; coutmax(1.23,2.34)endl; 重载方式重载方式靠将实参的个数及类型和所被调用的f()函数的形参的个数及类型一一比较来判断。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4040()作为重载函数至少在参数个数、参数类型上有所不同。若仅在返回类型上不同,编译器是无法区别的。如:void void func(int); func(int); int int func(int);func(int); /错误 int min(int ,int); int min(int ,int); int min(int,int,int); int min(int,int,int); /正确 int add(int,int); int add(int,int); double add(double,double); double add(double,double);/正确()typedef定义的类型只是给已有类型取另外一个名字,编译器不能将其同原类型区分。如: typedef INT int;typedef INT int; void func(int x) . void func(int x) . void func (INT x) void func (INT x) (3)重载函数一般应具有相同的功能,否则会破坏程序的可读性。注意事项注意事项修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域41414.6 4.6 函数的嵌套调用和递归调用函数的嵌套调用和递归调用嵌套调用嵌套调用嵌套调用嵌套调用递归调用递归调用递归调用递归调用修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4242嵌套调用嵌套调用函数的嵌套调用是指在执行被调用函数时,被函数的嵌套调用是指在执行被调用函数时,被调用函数又调用了其它函数。其关系可表示如图所调用函数又调用了其它函数。其关系可表示如图所示:示:修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4343 例例4.154.15 计算计算s=1s=1k k+2+2k k+3+3k k+N +N k k #include #include const int k=4;const int k=4;constconst int n=6; int n=6; /符号常量定义符号常量定义int int power(int,int); power(int,int); /求求幂幂的的函函数说明数说明int sum(int,int); int sum(int,int); /求和的函数说明求和的函数说明void main( )void main( ) coutSum of coutSum of 1 1k k+2+2k k+3+3k k+N +N k k = ;= ; coutsum(k,n)endl; coutsum(k,n)endl; /调用调用sumsum函数函数 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4444int sum(int k,int n)int sum(int k,int n)/*/*计算计算1 1到到n n的的k k次方之累加和次方之累加和*/*/ int s=0; int s=0; for(int i=1;i=n;i+) for(int i=1;i=n;i+) s+= power(i, k); s+= power(i, k); /累加累加 return return s; s; /调用调用f1f1函数函数 int power(int m,int n)int power(int m,int n) /*/*计算计算m m的的n n次方次方*/*/ int p=1, i; int p=1, i; for(i=1;in;i+) for(i=1;i1: n1时时 ,n!= n!= n * ( n-1 ) !n * ( n-1 ) ! n ! =1 n=1n * ( n-1 ) ! n1三、调用函数本身,但参数值趋于结束条件一、有一个使递归结束的条件二、当条件成立时,不再调用自己,而有确定值修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4646s:=fac(3)主程序fac(3):=fac(2)*3n=3fac(2):=fac(1)*2n=2fac(1):=1n=1fac:=6fac:=2fac:=1修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域47474.7 4.7 作用域作用域标识符的作用域规则标识符的作用域规则标识符的作用域规则标识符的作用域规则作用域的种类作用域的种类作用域的种类作用域的种类局部变量和全局变量局部变量和全局变量局部变量和全局变量局部变量和全局变量修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4848标识符的作用域规则标识符的作用域规则规则为规则为:标标识识符符只只能能在在说说明明它它或或定定义义它它的的范范围围内内是是可可见见的的,而在该范围之外是不可见的而在该范围之外是不可见的。说明有:说明有: 1 1、大大多多数数标标识识符符的的说说明明与与定定义义是是一一致致的的,只只有有少数例外。如:函数等。少数例外。如:函数等。2 2、范范围围有有大大有有小小。最最大大为为整整个个程程序序,最最小小为为块块,中间有文件和函数。中间有文件和函数。 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域4949作用域的种类作用域的种类不不同同的的标标识识符符定定义义在在不不同同的的范范围围内内有有不不同同的的作作用用域。按作用域的大小可分为:域。按作用域的大小可分为: 程序级程序级:包含着组成该程序的所有文件。:包含着组成该程序的所有文件。 文件级文件级:仅在定义它的文件内。:仅在定义它的文件内。 函数级函数级:在它所定义的函数体内。:在它所定义的函数体内。 块级块级: 定义在分程序中、语句块内。定义在分程序中、语句块内。注注意意:作作用用范范围围一一般般是是从从定定义义时时开开始始,到到相相应应范范围结束为止。围结束为止。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5050如:如:#include #include void main() void main() int x(3),y(5); /double x(3.5); int x(3),y(5); /double x(3.5); errorerror for (; for (;x0;x-x0;x-) ) int x(4);int x(4); coutcoutx xtty yt;t; coutendl coutendlx xtty yendl;endl; 在不同作用域中允许同名。在同一作用域中不允许同名。蓝色为函数作用域绿色为块作用域不为x x的原因是局局部优先部优先4 5 4 5 4 505修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5151局部变量和全局变量局部变量和全局变量1 1、局部变量、局部变量、局部变量、局部变量是指作用域在函数级和块级的变量。是指作用域在函数级和块级的变量。2 2、全局变量、全局变量、全局变量、全局变量是指作用域在程序级和文件级的变量。是指作用域在程序级和文件级的变量。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5252#includeint i(5); /外部变量外部变量externstatic int j(6); /外部静态变量外部静态变量void min(int x,int y ) /形参形参 int i(3); /自动变量自动变量 auto register int j(2); /寄存器变量寄存器变量 static int k(1); /内部静态变量内部静态变量 void main( ) 局部变量全局变量蓝色为文件作用域绿色为函数作用域注意:同名时是局部优先修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5353分析程序结果分析程序结果int a(5),b(7),c(10); coutatbtcendl; coutatbtcendl; int b(8);double c(8.8); coutatbtcendl; a=b; int c;c=b; coutatbtcendl; coutatbtcendl; coutatbtcendl;5 7 105 7 105 8 8.85 8 8.88 8 88 8 88 7 108 7 108 8 8.88 8 8.8修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域54544.8 C+4.8 C+的系统函数的系统函数概述概述概述概述C+C+系统将所提供的系统函数的说明分类放在不同系统将所提供的系统函数的说明分类放在不同的的.h .h文件(头文件)中。如:文件(头文件)中。如:数学处理函数(数学处理函数(math.hmath.h)、字符串处理函数)、字符串处理函数(string.hstring.h)、屏幕处理函数()、屏幕处理函数(conio.hconio.h)、图形处理函)、图形处理函数(数(graph.hgraph.h)。)。 conconconsole,console,控制台、安慰控制台、安慰 具体使用需要看所用的具体使用需要看所用的C+C+版本的帮助。注意:版本的帮助。注意:1 1、了解系统中有哪些系统函数。、了解系统中有哪些系统函数。2 2、了解函数位于哪个头文件中。、了解函数位于哪个头文件中。3 3、调用一个函数,须了解函数功能、参数和返回、调用一个函数,须了解函数功能、参数和返回值。值。修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5555如:如:如:如:#include #include #include#includevoid main( )void main( ) double I(30*3.1415/180); double I(30*3.1415/180); double x= double x=sin(I)sin(I); ; double y= double y=cos(I)cos(I); ; coutxyendl; coutxyendl; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5656输入输入15个数,用函数求和与平均值个数,用函数求和与平均值void main() double a15,s(0),ave(0); for(int i=0;i15;i+) cout输入第(i+1)ai; for(i=0;i15;i+) s+=ai; ave=s/15; cout和:sendl; cout平均值:aveendl;sum(15)ave(15)修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5757double sum(int x);/函数声明double ave(int x);/函数声明double a15,s(0); /全局变量void main() for(int i=0;i15;i+) cout输入第(i+1)ai; cout和:sum(15)endl; /函数调用 cout平均值:ave(15)endl;修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5858double sum(int x)/求和函数的定义 for(i=0;ix;i+) s+=ai; return s; double ave(int x) /求平均值函数的定义 return s/x; 修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域5959数组排序冒泡法数组排序冒泡法第第一一轮轮 B D C A E原原数数据据 B E D C A第第三三轮轮 B A C D E第第二二轮轮 B C A D E第第四四轮轮 A B C D E 4 3 2 1结论:轮数结论:轮数(外循环外循环)为为:n-1,每轮次数每轮次数(内循环内循环)为为:n-i修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域6060void main() const int N=6;int bN=89,3,56,44,12,99;for(int i=1;iN;i+) /控制轮数 for(int j=0;jbj+1) /如果交换两数 int t=bj;int t=bj; bj=bj+1; bj=bj+1; bj+1=t; bj+1=t; /输出排序后数组 for(int k=0;kN;k+)coutbkt;修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域6161int a10=8,5,7,8,3,5,6,1,9,1,n=10;for(i=0;i10;i+) for(j=i+1;jm; /输入int sqrtm=sqrt(m);for (int I=2;I=sqrtm;I+) if (m%I=0)/若能被某数整除 flag=0; /标志置0,并终止循环 break; else /否则标志置1, flag=1;if (flag) /如果全部比较后标志为1则是素数coutm is prime.n;else coutm isnt prime.n; 判断一个数是否素数?判断一个数是否素数?修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域6363int a10=8,5,7,8,3,5,6,1,9,1,b10,n=10;int i,j,flag,k=0;for(i=0;in;i+) flag=0;/用标志可简化编程 for(j=i+1;jn;j+) if(ai=aj) /若元素重复 flag=0;break; /置标志为0,并终止比较 elseflag=1; if(flag) /若比较一轮无重复 bk=ai,k+; /把此元素放入b /并使个数加1输入输入10个数,去除重复值后排序个数,去除重复值后排序修改时间:修改时间:修改时间:修改时间:2005200520052005年年年年2 2 2 2月月月月C+C+C+C+程序设计程序设计程序设计程序设计函数和作用域函数和作用域函数和作用域函数和作用域6464本讲作业本讲作业1、编程求出50至100之内所有素数之和(计算素数要求调用函数实现);2、设定数组的10个元素(有重复)并输出,调用函数(数组名作参数)去除数组重复值,再调用函数(数组名作参数)对无重复元素的数组排序,输出排序后的各元素;3、用函数重载的方式实现两个数的四则运算;4、看完吕凤翥书的P114至P123;5、教材P44第3题;6、看完教材第二章的内容!
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号