参数传递
来源:互联网 发布:汕头美工助理招聘信息 编辑:程序博客网 时间:2024/06/03 18:32
形参的初始化与变量的初始化一样:如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则它只是实参的别名.
非引用形参
普通的非引用类型的参数通过复制对应的实参实现初始化,不会改变实参本身的值.对这类形参的值得修改仅仅改变局部副本的值,当被调用函数执行完时,这些局部副本的值也将不存在.
1. const 形参
在调用函数时,如果该函数使用非引用的非const形参,则①既可以给该函数传递const实参,②也可以传递非const的实参。比如函数
int gcd(int v1,int v2){ while(v2) { int temp=v2; v2=v1%v2; v1=temp; } return v1;}const int i=3,j=6;int k=gcd(3,6); //okint i=3,j=6;int k=gcd(3,6); //ok
2. 形参为非引用的const类型
void fcn(const int i) /*fcn can read but not write to i*/
则不可以改变实参的局部副本,由于实参仍然是以副本的形式传递,因此传递给fcn的既可以是const对象,也可以是非const对象。
3. 复制实参的局限性
不适宜复制实参的情况包括:
- 当需要在函数中修改实参的值
- 当需要以大型对象作为实参传递时
- 没有办法实现对象的复制时
引用形参
函数swap要求交换两个实参的值,这时不适宜复制实参的值,所以这时用引用形参更方便。
void swap(int &v1, int &v2){ int temp=v2; v2=v1; v1=temp;}
引用形参直接关联到其绑定的对象,而非这些对象的副本,当调用swap()时,
swap(i, j);
形参v1只是对象i的另一个名字,对v1的任何修改实际上都是对i的修改。
利用引用形参的另一个好处是可以返回额外的信息,比如遍历vector中某个特定的元素,如果找到满座条件的元素,则返回指向该元素的迭代器,否则返回一个指向end的迭代器;此外,还希望返回该值出现的次数。
vector<int>::const_iterator find_val(vector<int>::const_iterator beg,vector<int>::const_iterator end,int val,vector<int>::size_type &occurs){ vector<int>::const_iterator res_iter=end; occurs=0; for(;beg!=end;++beg) { if(*beg==val) { if(res_iter==end) { res_iter=beg; } ++occurs; } } return res_iter;}
当对象较大时,利用const引用避免复制。比如比较两个string对象的长度:
bool isShorter(const string &s1, const string &s2){ return s1.size()<s2.size();}
每个形参都是const string 类型的引用,因为形参是引用,所以不复制形参,又因为形参是const引用,所以isShorter函数不能使用该引用来修改实参。
注意:如果使用引用形参的唯一目的是避免复制实参,则应将形参定义为const引用。
形参为指针的引用
两个指针的交换:
void ptrswap(int *&v1, int *&v2){ int *temp=v2; v2=v1; v1=temp;}
形参 int *&v1, 的定义应从右至左理解:v1是一个引用,与指向int型对象的指针相关联。
数组形参
作用在函数上的数组的两个特性:一是不能复制数组,二是使用数组名字时,数组名会自动转化为指向其第一个元素的指针。所以通常通过操纵指向数组中的元素的指针来处理数组。
- 数组参数的定义:
void printValues(int *)void printValues(int [])void printValues(int [10]) //最好别这样写,形参的长度容易引起误解
函数形参可以写成数组的形式。上面三种定义等价,形参类型都是int *。
- 通过引用传递数组。
如果形参是数组的引用,编译器不会将数组传化为指针,二是传递数组的引用本身,这种情况下,数组的大小成为形参和实参类型的一部分。编译器检查数组实参的大小与形参的大小是否匹配。
void printValues(int (&arr)[10])int main(){ int i=0,j[2]={0,1}; int k[10]={1,2,3,4,5,6,7,8,9,0}; printValues(&i); //error printValues(j); //error printValues(k); //ok}
- 参数传递
- 参数传递
- 参数传递
- 传递参数
- 参数传递
- 参数传递
- 参数传递
- 传递参数
- 参数传递
- 参数传递
- 参数传递
- 参数传递
- *参数传递*
- 参数传递
- 参数传递
- 参数传递
- 传递参数
- 参数传递
- Pthread的各种同步机制
- Android——Binder(AIDL)机制
- InterlliJ 文件代码模板的使用
- java基础学习总结——线程(一)
- 与Session的亲密接触&彻底掌握Java中Session Token Cookie
- 参数传递
- 算法学习【10】寻找质因数的个数
- 使用jekyll在Github上进行博客搭建
- 【一天一道LeetCode】#141. Linked List Cycle
- C++析构函数
- java基础学习总结——GUI编程(二)
- windows下telnet的NTLM 身份验证
- 真是无语了
- ROS里基本坐标系的理解:map,odom,base_link,base_laser