C++ Primer 学习笔记11 函数(函数调用、引用形参、非引用形参)
来源:互联网 发布:办公软件学习 编辑:程序博客网 时间:2024/06/03 03:57
函数的定义
求两个int型的最大公约数
int gcd(int v1,int v2){ while (v2) { int temp = v2; v2 = v1 % v2; v1 = temp; } return v1;}
1、函数调用
函数名(实参);
#include <iostream>using std::cin;using std::cout;using std::endl;int gcd(int v1,int v2);int main(){ cout<<"enter two numbers:\n";int i,j;cin>>i>>j;cout<<gcd(i,j)<<endl;system("pause");return 0;}int gcd(int v1,int v2){int temp;while(v2){temp=v2;v2=v1%v2;v1=temp;}return v1;}
函数在定义或者声明时,没有显式指定返回类型是不合法的。
如果两个参数具有相同的类型,则其类型必须重复声明:
int manip(int i,j) //error{//......}int manip(int i,int j) //ok{//......}
参数表中不能出现同名的参数。
2、参数传递
每次调用函数时,都会重新创建该函数的所有形参,此时所传递的实参将初始化对应的形参。
形参的初始化与变量的初始化一样:如果形参具有非引用类型,则复制实参的值;如果形参为引用类型,则它只是实参的别名。
2.1、非引用形参
普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。
int gcd(int v1,int v2){int temp;while(v2){temp=v2;v2=v1%v2;v1=temp;}return v1;}
While循环虽然修改了v1和v2的值,但这些仅局限于局部参数,而对调用gcd函数使用的实参没有任何影响。于是调用
gcd(i,j);则i与j的值不受gcd内执行的赋值操作的影响。
1、指针形参
函数的形参可以是指针,此时将复制实参指针。与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本。如果函数将新指针值赋给形参,主调函数使用的实参指针的值没有改变。
如果函数形参是非const类型的指针,则函数可通过指针实现赋值,修改指针所指向对象的值。
#include <iostream>using namespace std;void reset(int *ip){ *ip = 0; // changes the value of the object to which ip points ip = 0; // changes only the local value of ip; the argument is unchanged}int main(){ int i = 42; int *p = &i; cout << "i: " << *p << '\n'; // prints i: 42 reset(p); // changes *p but not p cout << "i: " << *p << endl; // ok: prints i: 0}
如果需要保护指针所指向对象的值,则形参需定义为const对象的指针:
void use_ptr(const int *p){}
我们既可以用int*也可以用const int*类型的实参调用use_ptr函数;但仅能用int*类型的实参传递给reset函数。这个差别来源于指针的初始化规则。可以将指向const对象的指针初始化为指向非const对象,但不可以让指向非const对象的指针指向const对象。
2、const形参
如果函数使用非引用的非const形参,则即可给该函数传递const实参也可传递非const实参。例如可以传递两个int型const对象调用gcd函数
const int i=3,j=6;int k=gcd(i,j);
如果形参定义为非引用的const类型:
void fcn(const int i){ }
则在函数中,不可以改变实参的局部副本。由于实参仍然是以副本形式传递,因此传递给fcn的既可以是const对象也可以是非const对象。
3、复制实参的局限性
复制实参并不是在所有的情况下都适合,不适宜复制实参的情况包括:
• 当需要在函数中修改实参的值时。
• 当需要以大型对象作为实参传递时。对实际的应用而言,复制对象所付出的时间和存储空间代价往往过大。
• 当没有办法实现对象的复制时。
对于上述几种情况,有效的解决办法是将形参定义为引用或指针类型。
2.2、引用形参
交换两个实参的值:
#include <iostream>using namespace std;void swap(int v1, int v2){ int tmp = v2; v2 = v1; // assigns new value to local copy of the argument v1 = tmp;} // local objects v1 and v2 no longer existint main(){ int i = 10; int j = 20; cout << "Before swap():\ti: " << i << "\tj: " << j << endl; swap(i, j); cout << "After swap():\ti: " << i << "\tj: " << j << endl;system("pause"); return 0;}
结果显示如下,两个实参的值并未交换,执行swap函数只是交换了实参的局部副本。
为了交换实参的值,需要将形参定义为引用类型
void swap(int &v1, int &v2){ int tmp = v2;v2 = v1; v1 = tmp;}
引用形参直接关联到其所绑定的对象,而并非这些对象的副本。因此,当调用swap
swap(i, j);
形参v1只是对象i的另一个名字,而v2则是对象j的另一个名字。对v1的任何修改实际上也是对i的修改。
如果使用引用形参的唯一目的是避免复制实参,则应将形参定义为const引用。
如果函数具有非const引用形参,则不能用const对象进行调用,因为此函数可以修改传递进来的对象,这就违背了实参的const特性。
- C++ Primer 学习笔记11 函数(函数调用、引用形参、非引用形参)
- C++Primer:函数(参数传递-非引用形参)
- C++Primer:函数(参数传递:引用形参)
- <<c++primer>>返回引用的函数调用
- C++函数引用形参和非引用形参
- 函数形参(非引用,指针,引用)
- 细嚼慢咽C++primer(3)——引用形参,内联函数,重载函数,指向函数的指针
- C++primer函数引用形参 左值和右值d额
- C++ 函数参数传递-非引用形参
- 函数参数传递1——非引用形参
- 函数的形参(非引用形参、指针形参、引用形参)
- C++函数的形参(非引用形参、指针形参、引用形参)
- 函数的形参(非引用形参、指针形参、引用形参)
- 函数引用形参问题
- C++ -- 函数:引用形参
- 函数形参const 引用
- C++primer学习笔记--右值引用
- C++ 学习之函数传参1:引用传参和非引用传参
- 九度题目1450:产生冠军
- 回归ACM
- bzoj 2768: [JLOI2010]冠军调查
- 如何实现两个数交换的交换以及宏定义的编写
- Scala的XML操作
- C++ Primer 学习笔记11 函数(函数调用、引用形参、非引用形参)
- iOS8开发~UI布局(三)深入理解autolayout
- Beat 'Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源码
- Scala的正则表达式regex操作
- iOS扩展navgation,支持锁定旋转方向
- ubuntu解决“系统的网络服务与此版本的网络管理器不兼容“问题
- 线性动态规划——专题
- iOS开发UI篇—UIPickerView控件简单介绍
- 三次握手,四次挥手『学习笔记』