数据结构 (五)c++函数和参数传递 按值传递 按引用传递
2015-10-19 09:47
1146 查看
按值传递:在这种参数传递的方式下,把实参的值传递给函数函数局部工作区相应的副本中。函数使用副本执行必要的计算,函数实际修改的是副本的值,实参的值不变。
按引用传递:在这种参数传递方式下,需将形参声明为引用类型,即在参数名前加上符号& ,当一个实参与一个引用类型结合时,被传递的不是实参的值,而是实参的地址。函数通过地址存取被引用的实参。执行函数调用后,实参的值将会改变。
若传递给函数的实参是一个对象(作为类的实例),在函数中就创造该对象的一个副本,在创造这个副本时不用调用该对象的构造函数,但在函数结束前要调用该副本的析构函数撤销这个副本,若采用引用方式传递对象,在函数中不会创建该对象的副本,因而也不需要撤销副本,但函数会改变引用传递的对象。
一、按值传递
这种传递方式继承自C语言。上述程序中的swap1和swap2函数使用这种传递方式,但是两种函数的作用并不相同。swap1函数没有达到交换a和b的值的目的,而swap2函数达到了交换a和b的值的目的;即使如此两者仍然同属于“按值传递”。
按值传递的特点是:在函数调用时,系统会在函数作用域新建形参存储空间并用实参对其初始化,所以调用时形参是实参的一个副本。然而为什么swap1和swap2效果不同呢?因为在swap1中a是main中a的副本、b是main中b的副本,更改swap1函数作用域中的a和b中的值并不影响main函数作用域中a和b的值;然而swap2中传递的是main中a和b的地址,经过地址可以更改传递过来的地址指向的值。
二、按引用传递
这种传递方式是C++语言新添加的特性。通过传递对参数的引用,可以允许函数访问(甚至修改)参数变量。要想按引用传递,必须将函数参数声明为引用。
函数swap3达到了交换a和b值的目的,从函数声明中可以看出swap3和swap1唯一的区别是在int后添加了一个字符“&”,正是这个字符使函数swap3中的a和b是main函数中a和b的引用。(“引用”即“别称”,注意:对引用对象的任何操作,作用于原来的对象。)
对比两种传递方式:
按值传递变量,需要有复制实参内存以初始化形参,所以这将带来一些开销。在讨论简单变量时,内置的类型(如int、float)的开销可以忽略不计,但对于大型的对象(如代表整个3D世界的大对象)来说,复制的代价会很高昂。C语言也提供了一种指针式的“按值传递”,也可以解决传递大对象时代价过高的问题,然而“指针”由于安全问题一直为众多程序员所诟病。故而C++又提供了一个按引用传递。
按引用传递:按值传递无法修改实参的值,因为它形参永远是实参的副本;然而按引用传递可以修改实参的值。
某些情况下,我们需要修改实参的值,而某些情况下,我们不想修改实参的值。
在C语言中我们的解决方案:如果不想修改我们就直接传递实参,如果对象太大我们就传递指针,并且声明指针是指向const对象的;如果想修改实参的值,我们只能传递实参的指针,然而此时指针就不能用const修饰了。
在C++中,我们仍然可以使用C中的方式,然而也可以使用“引用”方式:如果不想修改实参的值,我们使用const引用(就是“常量引用”)方式,这样就不可以通过引用修改被引用对象的值;如果想修改实参的值,则使用平常性的引用实参就可以了(如上程序)。 “`
使用const引用做函数参数的举例:void display(const vector& vec);
按引用传递:在这种参数传递方式下,需将形参声明为引用类型,即在参数名前加上符号& ,当一个实参与一个引用类型结合时,被传递的不是实参的值,而是实参的地址。函数通过地址存取被引用的实参。执行函数调用后,实参的值将会改变。
若传递给函数的实参是一个对象(作为类的实例),在函数中就创造该对象的一个副本,在创造这个副本时不用调用该对象的构造函数,但在函数结束前要调用该副本的析构函数撤销这个副本,若采用引用方式传递对象,在函数中不会创建该对象的副本,因而也不需要撤销副本,但函数会改变引用传递的对象。
include using namespace std; void swap1(int a,int b); void swap2(int* a,int *b); void swap3(int& a,int& b); int main() { int a=2,b=3; swap1(a,b); cout<<"a="<<a<<endl; cout<<"b="<<b<<endl; swap2(&a,&b); cout<<"a="<<a<<endl; cout<<"b="<<b<<endl; swap3(a,b); cout<<"a="<<a<<endl; cout<<"b="<<b<<endl; } void swap1(int a,int b) { int temp = a; a = b; b = temp; } void swap2(int* a,int *b) { int* temp =a; a = b; b = temp } void swap3(int& a,int& b) { int temp = a; a = b; b =temp; }
一、按值传递
这种传递方式继承自C语言。上述程序中的swap1和swap2函数使用这种传递方式,但是两种函数的作用并不相同。swap1函数没有达到交换a和b的值的目的,而swap2函数达到了交换a和b的值的目的;即使如此两者仍然同属于“按值传递”。
按值传递的特点是:在函数调用时,系统会在函数作用域新建形参存储空间并用实参对其初始化,所以调用时形参是实参的一个副本。然而为什么swap1和swap2效果不同呢?因为在swap1中a是main中a的副本、b是main中b的副本,更改swap1函数作用域中的a和b中的值并不影响main函数作用域中a和b的值;然而swap2中传递的是main中a和b的地址,经过地址可以更改传递过来的地址指向的值。
二、按引用传递
这种传递方式是C++语言新添加的特性。通过传递对参数的引用,可以允许函数访问(甚至修改)参数变量。要想按引用传递,必须将函数参数声明为引用。
函数swap3达到了交换a和b值的目的,从函数声明中可以看出swap3和swap1唯一的区别是在int后添加了一个字符“&”,正是这个字符使函数swap3中的a和b是main函数中a和b的引用。(“引用”即“别称”,注意:对引用对象的任何操作,作用于原来的对象。)
对比两种传递方式:
按值传递变量,需要有复制实参内存以初始化形参,所以这将带来一些开销。在讨论简单变量时,内置的类型(如int、float)的开销可以忽略不计,但对于大型的对象(如代表整个3D世界的大对象)来说,复制的代价会很高昂。C语言也提供了一种指针式的“按值传递”,也可以解决传递大对象时代价过高的问题,然而“指针”由于安全问题一直为众多程序员所诟病。故而C++又提供了一个按引用传递。
按引用传递:按值传递无法修改实参的值,因为它形参永远是实参的副本;然而按引用传递可以修改实参的值。
某些情况下,我们需要修改实参的值,而某些情况下,我们不想修改实参的值。
在C语言中我们的解决方案:如果不想修改我们就直接传递实参,如果对象太大我们就传递指针,并且声明指针是指向const对象的;如果想修改实参的值,我们只能传递实参的指针,然而此时指针就不能用const修饰了。
在C++中,我们仍然可以使用C中的方式,然而也可以使用“引用”方式:如果不想修改实参的值,我们使用const引用(就是“常量引用”)方式,这样就不可以通过引用修改被引用对象的值;如果想修改实参的值,则使用平常性的引用实参就可以了(如上程序)。 “`
使用const引用做函数参数的举例:void display(const vector& vec);
相关文章推荐
- 数据结构:字典树的基本使用
- 数据结构:字典树的基本使用
- Hadoop集群管理 Namenode的目录数据结构
- 数据结构之顺序表
- [题解+总结]20151017数据结构
- 数据结构与算法80道
- 第六周--数据结构之自建算法库之迷宫问题(用队列)
- 数据结构之图
- 第六周--数据结构之自建算法库之迷宫问题(用栈结构)
- 数据结构基本概念
- 中国大学MOOC-陈越、何钦铭-数据结构 列出连通集
- 第六周--数据结构之自建算法库之表达式求值(用栈结构)
- 【ShancoLove】带你看数据结构——第八课:二叉树概念
- 第六周--数据结构之自建算法库之链式队列
- 第六周--数据结构 项目之顺序环形队列
- 第六周--数据结构【线性表(二)链表】项目之链栈
- 数据结构——排序 (二)
- 第六周--数据结构【线性表(二)链表】项目之顺序栈
- 数据结构与算法之栈
- 数据结构导论——自考