关于引用,做参数,返回值


引用仅仅给原变量起别名,和原变量是同一个东西,一个东西的两个名字。

关于引用

	int a=2;
	int &b=a;
	b=56;			//  b是 a的一个别名, b 和 a 的地址是一样的 

声明一个引用时,必须同时使之初始化

int &r; // 不合法
int &r = a; // 合法

引用在初始化之后不可修改

int &r = a; // 初始化,   r 是 a 的引用
int b = 885;
r = b; 	// 只是赋值操作,不是更改引用

常引用

const int &z=x;						// z不能做左值, 即 z=32; 这样的事情是不被允许的 

引用只能引用变量,不能引用常量和表达式。

数组名是数组首元素的地址,本身不是一个占有存储空间的变量
char c[6]="hello";
char &rc=c;						// error

指针变量的引用

int i=5;
int *p=&i;
int * &pt=p;											// 建立指针变量 p的引用 pt
				pt代表一个int *类型的数据对象(即指针变量)

数组的引用

int a[10];
int (&b)[10] = a;

b 和 a 等价

关于数组的引用和引用的数组

函数参数:传引用 和 传指针 的区别

传指针

void swap(int* p1,int* p2){
    int* temp=p1;
    p1=p2;
    p2=temp;
}

int main(){
 	int a=1,b=3;
    int *p1=&a,*p2=&b;
    swap(p1,p2);
}
  • swap函数中 p1和p2 确实交换了指向 ,但swap函数中的 p1 p2 与main函数中的 p1 p2 不是同一个 。
  • 因为此时有四个变量,main中两个(p1,p2),swap中两个(p1,p2)。
  • swap函数的p1指向其他地方时,和main函数中的p1没有任何关系。

传引用

void swap(int* &p1,int* &p2){
    int* temp=p1;					
    p1=p2;
    p2=temp;
}
  • 此时swap函数中的 p1 p2是外面的别名,只不过名字一样,和外面是同一个东西。
void f(int &x);
f(y); 							// 在 f 里面对 x做任何的修改, 外面的 y 就变了。

做返回值

用引用做返回值的最大好处是,在内存中不产生被返回值的副本,速度快。

//  不能返回局部变量的引用
int & test01(){
	int a=10;				// 将 a改为静态变量是可以的 static int a=10;
	return a;
}

引用做右值的例子

float temp;		// 全局变量 
float &fn2(float r){ 				// &说明返回的是temp的引用,换句话说就是返回temp本身
    temp=r*r*3.14;
    return temp;
}

float c=fn2(5.0);				// 相当于执行 float c=temp;		c和 temp只是值一样,他们是两个变量    		c并不是 temp的别名。
float &d=fn2(5.0);				// 相当于执行 float &d=temp;		此时 d成为变量 temp的别名。		修改 d, temp随之变化。

引用做左值的例子

int arrs[5]={12,13,14,15,16};
int &setValues(int i){
	return arrs[i];					函数返回 arrs[i]的引用,也可以理解为 arrs[i]本身
}

int main(){
	cout<<"更改前:"<<endl; 
	for(int i=0;i<5;i++){
		cout<<"arrs["<<i<<"]:"<<arrs[i]<<endl;
	}
	setValues(1)=12345;			// 实质是 arrs[1]=12345; 
	setValues(3)=547395;		// 实质是 arrs[3]=547395; 
	cout<<"更改后:"<<endl;
	for(int i=0;i<5;i++){
		cout<<"arrs["<<i<<"]:"<<arrs[i]<<endl;
	}	
}

引用的本质

本质是指针常量。

int &ref=a;		// 编译器自动转换为 int *const ref =&a;   
ref=20;			// 当我们在做这件事情的时候,  编译器自动帮我们转换为 *ref=20;

Attention

非 const 的引用 不能绑定:临时对象,字面常量,const常变量

[Error] invalid initialization of non-const reference of type 'Complex&' from an rvalue of type 'Complex'
[Error] cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'|
int i;
void func(int &n);
for(i=1;i<=6;i++){
	func(i*4);			// wrong
}
i*4 只是一个临时变量。
可以改为   void func(const int &n);

常引用

const int & b;				

所引用的对象不会被更新,并且b可以绑定到一个常对象
对于基本数据类型的引用,不能修改该数据的值
对于类类型的引用,不能修改它的数据成员,也不可以调用它的非 const 的成员函数。
常引用经常拿来做形参

参考:
C/C++ 引用作为函数的返回值
C++ 引用 reference

值传递 (pass by value),指针传递(pass by pointer),当发生函数调用时,需要给形参分配存储单元、当传递是对象时,要调用拷贝构造函数。
而且指针最后析构时,要处理内存释放问题。

引用传递(pass by refenrence),在内存中没有产生形参。效率大大提高!也不用处理指针的析构问题。
在形参中数据较为复杂时(比如以对象作为参数),应该尽量使用引用,少利用指针与值传递。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值