C++的三种传递参数到函数的方法:按值传递,用引用参数按引用传递,用指针参数按引用传递

平时见的较多的是按值传递(pass-by-value)和按引用传递(pass-by-reference)
这两种函数的形参传递方式.

pass-by-value:当用这种方式传递形参时,会在函数调用的堆栈上,产生一份实参值的副本,然后将副本传递给被调用的函数,对副本的修改不影响调用者中原始变量的值。

pass-by-reference:当用这种方式传递形参时,调用者使得被调用函数可以直接访问调用者的数据,并且如果被调用函数需要,还可以修改这些数据。

按引用传递,分为用引用参数和用指针参数。

于是先用例子说明

#include <iostream>
using namespace std;
class M
{
public:
	M(int i, int j) { x=i; y=j; }
 	void setxy(int i, int j)
	{
		x=i;
		y=j;
	}
 	void print() 
	{
		cout<<x<<","<<y<<endl; 
	}
private:
	int x, y;
};

void fun(M m1, M &m2, M *m3) 
{
	M *p3 =&m1;
	M *p4 =&m2;
	M *p5 = m3;
	cout<<"按值传递的地址 *p3="<<static_cast<const void *>(p3)<<endl;				//按值传递的地址
	cout<<"用引用参数按引用传递的地址 *p4="<<static_cast<const void *>(p4)<<endl;	//用引用参数按引用传递的地址
	cout<<"用指针参数按引用传递的地址 *p5="<<static_cast<const void *>(p5)<<endl;	//用指针参数按引用传递的地址
	m1.setxy(12, 15);
	m2.setxy(22, 25);
	(*m3).setxy(32, 35);
}

void main()
{
	M p(5, 7), q(6,8), z(7,9);
	M *pp = &z;
	M *p1 = &p;
	M *p2 = &q;
	cout<<"按值 *p1="<<static_cast<const void *>(p1)<<endl;
	cout<<"用引用参数 *p2="<<static_cast<const void *>(p2)<<endl;
	cout<<"用指针参数 *pp="<<static_cast<const void *>(pp)<<endl;
	fun(p, q, pp);
	p.print();
	q.print();
	z.print();
}
结果可想而知,p的成员值依旧是(5,7),而q和z都更改为set后的值。


还有就是引用参数与指针作参数的区别?

1:
指针通过对地址的操作进而改变实参,
引用是以别名的方式对实参的直接处理达到同样效果。

2:

引用肯定会指向一个对象,引用应被初始化,而指针可以是NULL:

string& rs; // 错误,引用必须被初始化
string s("xyzzy");
string& rs = s; // 正确,rs指向s

指针没有这样的限制。

string *ps; // 未初始化的指针

                  // 合法但危险


3:

不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性

void printDouble(const double& rd)
  {
   cout << rd; // 不需要测试rd,它
  }       // 肯定指向一个double值


相反,指针则应该总是被测试,防止其为空:

void printDouble(const double *pd)
  {
   if (pd)
   {// 检查是否为NULL
    cout << *pd;
   }
  }

4:

指针可以被重新赋值以指向另一个不同的对象,但引用则总是指向在初始化时被指定的对象,以后不能改变。

string s1("Nancy");
string s2("Clancy");

string& rs = s1; // rs 引用 s1
string *ps = &s1; // ps 指向 s1
rs = s2; // rs 仍旧引用s1
       // 但是 s1的值现在是"Clancy"

ps = &s2; // ps 现在指向 s2;// s1 没有改变

总的来说,当使用指针,一是考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是需要能够在不同的时刻指向不同的对象(在这种情况下,能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么应该使用引用。


利用Vector

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v(7); //建立整形向量(vector),大小为7
	v[5] = 10; // 这个被赋值的目标对象就是操作符[]返回的值
	cout<<"vector<int> v<7>:"<<endl;
	for (int i =0;i!=v.size();i++)
	{
		cout<<v[i]<<" ";
	}
	cout<<endl;
	int j =10;
	v[5]=j;
	cout<<"v[5]= "<<v[5]<<endl;
	j=10;
	cout<<"v[5]= "<<v[5]<<endl;
	cout<<"vector<int*>"<<endl;
	vector<int*> pv(7);
	int i =10;
	pv[5]=&i;
	cout<<"pv[5]= "<<*pv[5]<<endl;
	i = 5;
	cout<<"pv[5]= "<<*pv[5]<<endl;
	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值