admin 管理员组文章数量: 1087649
2024年12月29日发(作者:开源云平台)
本文作者:黄邦勇帅
本文是学习C++的基础内容,在学习C++之前就应该完全弄清楚函数是怎么回事,本文详尽的介绍了函数的各种情况及
作用,本文是对函数未了解透彻的读者的最好选择,本文内容全面,简单易懂。
本文内容完全属于个人见解与参考文现的作者无关,其中难免有误解之处,望指出更正。
声明:禁止抄袭本文,若需要转载本文请注明转载的网址,或者注明转载自“黄邦勇帅”。
主要参考文献:
1、C++..第五版.中文版[美]Stephen Prata著孙建春韦强译人民邮电出版社2005年5月
2、C++..第四版.中文版Stanley n、Barbara 著李师贤等译人民邮电出版社2006年3月
3、C++..第三版.中文版Stanley n等著潘爱民张丽译中国电力出版社2002年5月
4、C++入门经典第三版[美]Ivor Horton著李予敏译清华大学出版社2006年1月
5、C++参考大全第四版[美]Herbert Schidt著周志荣朱德芳于秀山等译电子工业出版社2003年9月
6、21天学通第四版C++ [美]Jesse Liberty著康博创作室译人民邮电出版社2002年3月
12.函数
12.1函数原型
.
在C++中所有函数都必须在使用之前进行声明.函数原型除
了没有函数体外,它与函数的定义一样.函数原型指定3个
方面的内容,函数的反回类型,函数的参数类型,参数数量.
在首次调用函数之前编译器需要知道这3方面的信息,所以函
数原型应放在main函数之前.声明一个函数时可以不用参数
名,所以定义函数时可以使用与函数原型不同的参数名.
例:int hyong (int i,int j,int k);
//注意:返回类型不能是数组,声明函数原型,必须有
//分号,函数hyong的反回类型为int
void mibaoqi(int i);//声明一个不反回值的函数
main ()
{int x=10, y=11, z=2,n;
n=hyong (x,y,z); //调用函数hyong,且将hyong
//的反回值赋给变量n;
mibaoqi (x); //调用无反回类型的函数mibaoqi
cout< int hyong (int i, int j, int k)//定义函数体 {int m; return m=x*y*z; //使用return语句反回值; /* return语句的反回类型必须与hyong的反回类型相兼 容,函数遇到return语句则反回到调用处*/ m=20;} //此语句被忽略,因为在return后的语 //句将被忽略 void mibaoqi (int i) {int x; x=i; cout< return; } //无反回值的return语句,注意分号 12.2函数通式. 函数通式为:反回类型函数名(参数列表) {语句} 如void hyong (int i,int j){语句},就定义了一个名为 hyong的无反回类型的函数,该函数有两个参数,参数 之间用逗号分开.注意:函数的反回类型不能是数组.不 能在一个函数中定义另一个函数 12.3使用return反回值 函数遇到return语句,正在执行的程序就会立即返回到其调用 函数所在的位置,函数的其他代码将被忽略.一个函数可以包 含几个return语句,一旦遇到return语句,函数就会反回. 如果有返回值的函数遇到结束的大括号而返回,那么就会返回一个未定义的值(即未知值).可以将有反回值的函数的反 回值赋给一个变量,当没有变量接收这个反回值的时候,这个函数仍反回值,但这个值被丢弃了. return语句有两种形式,一种不返回值,形式为return;注意后面有一个分号,使用此语句,可把函数声明为反回void类 型,即函数无反回值.另一种为返回值,形式为return 要反回的值; 注意:函数的返回值的类型必须与函数的反回类型相兼容. 12.4函数的参数 12.4.1 形参和实参 传递给函数的值称为实参.定义函数时声明的接受函数实参的变量称为形参. 12.4.2 参数的传递方法 例:值调用和引用调用对实参的影响 void swap (int x, int y) //交换实参的值 参数的传递方法有值传递和引用调用两种,其中值调用是 void swap(int *x, int *y) 将实参的值复制到形参中,因此形参的变化不会对实参产 生影响,而引用调用是将实参的地址而不是值传递给形参, main() { int i=10, j=20; cout< 因此形参指向调用实参的地址,形参的变化就会影响到调 swap ( i, j); //值调用,不会交换实参的值 用函数的实参. cout< 引用调用 swap (&i , &j) //引用调用,将交换实参的值 1.传递指针实参 要传递指针类型的实参,则形参就必须声明为指针类型, cout< void swap (int x, int y) 参数传递时是将实参的地址传递给形参,所以当使用指 { int temp; temp = x; x=y; y=temp;} 针的函数执行操作时,是在对指针所指向的变量进行操 void swap (int *x, int *y) 作,因此函数可以改变实参的值 { int temp; temp =*x; *x=*y; *y=temp;} 2.传递数组实参 //此函数会改变实参的值,因为形参是指向实参的指针,对 在给函数传递数组参数时,传递的是数组的第一个元素 形参的操作就是对指向实参地址的变量的操作 的地址,而不是整个数组的一个副本.这意味着形参必 须声明为兼容的类型.有3种方法可以声明接受数组的 例:传递数组 void f (int x[10]); //将形参声明为具有相同容量和类型 形参. //的数组,在这里形参接收的是实参的 a.将形参声明为一个数组.这个数组和调用函数时使用的 //址址,而不是整个数组的值 数组具有相同的类型和容量.在这种方式中,即使形参 具有和实参相同的整型数组,C++编译器也也会将其转换 void f (int x[]); //将形参声明为没有大小的数组,这种 //类型也是接收的实参的地址 成int指针.因为没有形参可以实际接收整个数组.由于 只传递数组的指针,所以必须有一个指针参数接收它. void f (int *x); //将形参声明为一个指针 main () b.将形参声明为一个没有大小的数组.这种类型也是接 { int t [10], i; for (i=0;i<10;++i) t[i]=i; f (t); } 收的实参的地址 c.将形参声明为一个指针.这是编写C++程序的常用方法. void f ( int x[10]) //f函数定义相同,只是形参形式不同 3.传递字符串实参 {for (int i=0;i<10;i++) cout< 在将字符串传递给函数时,实际上只传递指向字符串开头处的指针.形参应声明为char *类型的指针. 4.引用类型的形参 a.使用引用类型的形参时,会自动将实参的地址(不是值)传递给形参,在函数中对引用参数操作被自动解除引用, 所以不需要使用指针运算符 b.声明引用类型的形参的方法为在形参变量的名称前加上&运算符就可以声明引用类型的形参了,对引用参数的 操作会影响到实参的值,而不是引用参数本身. 例:引用类型的形参例:使用引用形参交换实参的值 void swap (int &x, int &y); void f (int &i); //声明引用类型形参的函数 main () main() {int i=10, j=20; cout< { int x=1; cout< f (x); //引用参数自动传递x的地址,swap(i, j); cout< void swap (int &x, int &y) //在x前不用加&地址引用符号 { int temp; temp=x; x=y; y=temp;} cout< //交换实参i和j的值,在x和y前不用加*指针运算符, void f (int &i) {i = 10;} //此语句是对i所引用的变量x的操作,也就是对x赋值此语句是对x和y引用的变量i和j的操作,并不是对 10,并不是对i赋值,注意在引用类型形参的函数调用x和y的操作,在这里x和y就是i和j地址,对x和y 中i前面不用加*指针符号,在这里变量i就是一个地址的操作就是对i和j的操作 12.5返回类型为指针和引用的函数 a.如果函数的返回类型是引用,则函数的返回值是一个隐含的指针, 也就是说函数返回的是一个地址,即return语句后的反回类型不 用加地符运算符&,函数也会自动将其地址反回,例如int x; return x; 则函数会返回变量x的地址,而不是x的值.如果是返回的某个变 量的地址,则对这个函数的操作也就相当于是对这个变量的操作. 所以函数可以用于赋值语句的左边,即函数可以当作变量来使用. b.如果函数的返回类型是指针,那么return语句中使用的值必须是与 指针相兼容,也就是说return必须反回的是地址.返回指针类型的 函数也可以当作变量来使用. c. 千万不要反回局部对象的引用或指针。因为当函数执行完毕后, 将释放分配给局部对象的存储空间,此时对局部对象的引用或 例:返回类型为指针的函数 intj=12;int*f(); main() {intx,y=15; x=*f();//把f()所指向的变量的值赋给x *f()=y; /* 函数f当作变量来使用,此处相当于全局变量j, 即f()所指向的地址的变量j */ cout<<*f()< /* 再次调用f,但f只反回j的值,j在前面被赋于了 15,在这里并没改变全局变量j的值,所以输出15 */ ();}//暂停,等待用户按回车 int*f() {return&j;} //应反回地址以与指针兼容 指针就会指向不确定的内存。 例:返回类型为引用的函数 //注意此处声明全局变量并赋值 intj=12;int&f(); main() {intx,y=15; x=f();//把f()引用的变量j的值赋给x f()=y; /* 函数f当作变量来使用,此处相当于对f()引用的变 量赋值,注意f()前不用加*号*/ 例:即使在cout< //注意此处声明全局变量不赋值 intj;int&f(); main() {intx,y=15; x=f();//调用函数f,且对j赋值12.所以x的值为12; cout< f()=y; //再次调用函数f.且对j赋值12.并把y的值15赋给f()引用的变量 //j,所以j现在的值为15 cout< /* 再次调用f,但f只反回j的值,j在前面被赋于了15, 在这里并没改变全局变量j的值,所以输出15 */ cout< cout< /* 注意,这里将再次调用函数f,并不是直接输出f()的值,且对j再次赋值 12,j的值由先前的15变回12,然后反回f引用的变量j的值,所以输出f()的值 为12 */ } ();}//暂停,等待用户按回车 int&f(){returnj;} //反回j的地址,此处不用加地址运算符 int&f(){j=12; returnj;}//对全局变量j赋值12 int &h() {int i=12;return i;}//错误,不能反回局部对象的引用 12.6引用变量 引用变量必须指向某些对象,因此,声明引用变量时必须进行初始化.例如int j;int &i=j; i=10;这里是把j的地址赋给 引用变量i,而i=10并不是对i赋值,而是对i所引用的变量j赋值,所以这里j被赋值为10.语句int &j;是错误的引用 变量必须被初始化. 例:函数重载 void f (int x); 12.7函数重载 函数重载,参数类型 void f (short x); 或数量必须不同 使用相同名称但参数不同的函数就叫函数重载, void f (double x); 函数重载必须是每个重载函数的参数类型或数 void f (int x, int y); main () 量必须不同.调用重载的函数时,就会执行形 { int i =10, j=11; short s=99; double d=10.1; float t=11.5F; f (i); //调用函数f (int x) 参与实参相匹配的那个函数. f (i, j); //调用函数f(intx, int y) f (s); //调用匹配的函数f (short x) 12.8函数默认参数 f (d); //调用函数f (double x) Ê.声明默认参数和声明变量相似,例如 f (t);} //调用函数f (double x)此处发生自动类型转换 void f (int x, int y) {cout<< x< void f (int x=0, int y=90);调用方法有三种, void f (int x) { cout< void f (short x) {cout< 如f (1,2),将1传给x,2传给y, f (11)将值11赋给x,y使用默认值90,f()参数x和y都使用默认值. 2.默认参数只能指定一次,并且只能在文件中首次声明函数时或函数原型中指定,例如在函数原型中指定默认参数,但 如果在函数原型中指定了默认参数,又在函数定义时指定相同或不同默认参数的值时就会出错. 3.可以为重载函数的每个版本指定不同的默认参数,即重载函数的不同版本可以有不同的默认参数. 4.接收默认值的所有参数都必须出现在不接收默认值的参数的右侧,例如f (int x ,int y=10);是正确的,但是f(int x=10, int y);就是错误的. 5.一旦开始定义接受默认值的参数,后面就不能指定不带默认值的参数,例如f (int x, int y=10, int z)就是错误的,必须 为z指定默认参数. 6.调用函数时如果其中某个参数使用了默认值,那么这个参数之后的每个参数都必须使用默认值.例如定义函数f(int x, int y=10, int z=12),调用函数f ( 10,,15)就是错误的. 12.9 函数重载与多义性 1.多义性:即编译器不能在两个正确重载的函数间作出先择.多义性的语句就是错误. 2.自动类型转换引起的多义性:如定义函数f (float i)和f (double i),当用语句f (11)调用时就会出现错误,函数是调用 f (float i)呢?还是f (double i)呢,对于浮点常量C++会自动转换为double型,如f (11.5)就会调用f (double i),不会出 现多义性 3.默认参数引起的多义性:如定义函数f (int i)和f (int i, int j=2),则调用语句f (10)就会出现多义性,是调用f (int i)呢还 是调用f (int i, int j=2)呢? 12.10 函数指针(即指向函数的指针) int (*hyong)() 1.int (*hyong)(int a, int b)该语句声明了一个指向函数的指针hyong注意()是必须的。hyong指向的函数带有两个int型的 形参,和int型的反回值。 2.函数指针的初始化:函数名就是函数的地址,所以在给函数指针赋值时只须给出函数名即可,函数名后不能有括号。 赋给函数指针的函数必须和函数指针有相同的反回类型,相同的形参列表,只要稍微有一点不同就不能赋值。 3.函数指针的调用:可以把函数指针当函数名一样使用来调用函数,即可以这样调用函数指针hyong(4,5),还有种形式 为(*hyong)(4,5) 作者:黄邦勇帅
版权声明:本文标题:C++函数专题 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1735566597a1677006.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论