C++中的引用

一、概述与定义

    先说下变量:变量名实质上是一段连续存储空间的别名,程序中通过变量来申请并命名内存空间,通过变量的名字可以使用存储空间。

    引用:在C++中引用可以看作一个已定义变量的别名。

    引用的语法: Type& name = var;

int main()
{
	int a = 10;
	int &b = a;

	cout << "b->" << b << endl;
	cout << "a->" << a << endl;

	cout << "&a->" << &a << endl;
	cout << "&b->" << &b << endl;

	system("pause");
	return 0;
}


输出结果:

   

二、引用作函数参数

引用作函数参数时也是变量的别名。

#include <iostream>

using namespace std;

struct Student
{
	int num;
	int age;
};

//引用作函数的参数就是实参的别名
void PrintStu(Student& stu)
{
	cout << stu.num << endl;
	stu.age = 12;
}

int main()
{
	Student stu1;
	Student& stu2 = stu1;//必需进行初始化
	stu2.num = 1;
	stu2.age = 10;
	PrintStu(stu1);	
	cout << stu1.age << endl;
	system("pause");
	return 0;
}

运行结果:


三、引用的本质

先看下下面的程序:

#include <iostream>

using namespace std;

struct Student {
	int &a;
	int c;
};
int main()
{
	printf("sizeof(Student) %d\n", sizeof(Student));
	system("pause");
	return 0;
}
运行结果:


这个现象的背后隐藏了多少不为人知的秘密?

引用是一个有地址,引用是常量

引用在C++中的内部实现是一个常指针;Type& name <==>Type* const name。

C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。

从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏:当实参传给形参引用的时候,只不过是c++编译器帮我们程序员手工取了一个实参地址,传给了形参引用(常量指针)

四、引用注意事项

4.1当函数返回值为引用时

若返回栈变量,可能乱码,也可能不乱码。

不能成为其它引用的初始值

不能作为左值使用

#include <iostream>

using namespace std;

int getA()
{
	int a = 10;
	return a;
}

int& getA2()
{
	int a = 10;
	return a;
}

int main()
{
	int a1 = 0;
	int a2 = 0;

	a1 = getA();
	a2 = getA2();
	int &a3 = getA2();//乱码

	cout << "a1->" << a1 << endl;
	cout << "a2->" << a2 << endl;
	cout << "a3->" << a3 << endl;
	
	system("pause");
	return 0;
}

运行结果:


4.2若返回静态变量或全局变量

可以成为其他引用的初始值

即可作为右值使用,也可作为左值使用

#include <iostream>

using namespace std;

static int a;
int getA()
{
    a = 10;
	return a;
}

int& getA2()
{
    a = 10;
	return a;
}

int main()
{
	int a1 = 0;
	int a2 = 0;

	a1 = getA();
	a2 = getA2();
	int &a3 = getA2();

	cout << "a1->" << a1 << endl;
	cout << "a2->" << a2 << endl;
	cout << "a3->" << a3 << endl;
	
	system("pause");
	return 0;
}

运行结果:

4.3当被 调用的波函数当左值的时候,必须返回一个引用

#include <iostream>

using namespace std;

int& fun()
{
	static int a = 10;
	a++;
	cout << "a->" << a << endl;
	return a;
}
//相当于手工打造做左值的条件
int* fun2()
{
	static int a = 10;
	a++;
	cout << "a->" << a << endl;
	return &a;
}
int main()
{
	fun() = 100;
	fun();
	*(fun2()) = 200;
	fun2();
	system("pause");
	return 0;
}

 运算结果:

4.4结论:

用引用去接收函数的返回值,是不是乱码,关键是看返回 的内存空间是不是被编译器回收了。

 五、指针的引用

#include <iostream>

using namespace std;

struct Student
{
	char name[50];
	int age;
};

int getStu(Student **stu)
{
	Student *p1 = (Student*)malloc(sizeof(Student));
	if (p1 == NULL)
		return -1;
	memset(p1, 0, sizeof(Student));
	p1->age = 16;
	*stu = p1;
	return 0;
}

int getStu2(Student* &stu)
{
	stu = (Student*)malloc(sizeof(Student));
	stu->age = 16;
	return 0;
}
int main()
{
	Student *p = NULL;
	getStu2(p);//与getStu(&p); 相当

	system("pause");
	return 0;
}

六、const引用

分两种情况:

6.1用变量对const引用初始化

const引用让变量所只内存空间拥有只读属性,这种用途用得比较多的有作波函数的形参

        int a = 10;
	const int &b = a; 
	a=11;//正确
	b=11;//错误

6.2用常量对const引用初始化

#include <iostream>

using namespace std;


int main()
{
	const int &a = 10;  //去掉const编译不通过
	
	int *p = (int *)&a; //注意需要(int *)

	*p = 12;
	printf("a:%d", a);
	system("pause");
	return 0;
}

  当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名,使用常量对const引用初始化后将生成一个只读变量。

  另外,const引用都可以通过指针支修改变量的值。这区别于我的另外一篇博客,c/c++中的const。





 



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值