C++中的引用

引用是C++新引进的概念在C语言中是不存在的,接下里啊重点介绍引用。

说到引用首先得提一个概念:变量名,变量名是指上是一段连续储存空间的别名,算是一个标号,门牌号,程序中通过变量来申请并命名内存空间。通过变量的名字来使用内存空间。

1.引用的概念

引用:相当于一个变量的别名,相当于给这个变量的内存空间重新起了第二个名字。

用法:如下代码

int main()
{
	int a = 10;//定义变量a
	int &b = a;//这就是引用,b对a的引用,现在b和a是同一块内存空间,可用b来修改a的值
	b = 100;
	cout << a << endl;
	cout << b << endl;
	getchar();
	return 0;
}

2.引用是属于c++的语法范畴

3.引用做函数参数

注意://普通引用在声明的时候必须用其他的变量初始化

           //但是引用做函数的参数的时候不用初始化


4.复杂数据类型做函数参数的引用

struct stu//定义结构体变量
{
	int a;
};
void fun1(stu *p)//指针参数,可以通过指针修改结构体的数据
{
	cout << p->a << endl;
}
void fun2(stu &p)//引用做参数,可以修改结构体的数据
{
	cout << p.a << endl;
}
void fun3(stu p)//变量名做参数,不能修改结构体的数据
{
	cout << p.a << endl;
}
int main()
{ 
	stu tl;
	tl.a = 10;
	fun1(&tl);//传过去结构体变量的地址
	fun2(tl);//p相当于tl的别名
	fun3(tl);//将tl内存中的数据复制一份传递过去
	getchar();
	return 0;
}
5.引用的意义

//引用作为变量的别名而出现,在一些场合可以代替指针
//引用相对于指针有更好的可读性和实用性

比如上面的交换两个数的值,引用更加的简单。

6.引用的本质----C++编译器如何实现的引用

int a=10;
int &b=a;//必须初始化b

①单独使用引用时必须初始化,类似于const int a=10,必须初始化一样,所以这里的b好像一个常量

a和b均是同一块内存空间的门牌号

②引用占内存空间吗?

请问这个结构体所占大小是多少?

struct stu
{
	char name[24];//24
	int a;//4
	int &b;//4
	int &c;//4
};

经检验大小为36

由此可由推出int &b,int &c各占四个字节

再次验证

struct stu
{
	char name[24];//24
	int a;//4
	char &b;//4
	char &c;//4
};
此结构体大小也为36,

所以可得引用所占的空间和指针变量很类似。

总上所述可以得结论:引用的本质就是char *const p;引用在C++内部实现是用常指针实现的,所以引用所占的内存空间和指针大小相同,引用会让人误认为说变量的别名,没有自己的储存空间,这是C++为了实用性做出的细节隐蔽


7.函数返回值是引用(引用当左值)

①当函数返回值为引用://若返回栈变量,则不能成为其他引用的初始化值,也不能作为左值使用

int fun1()
{
	int a ;
	a = 10;
	return a;
}
int &fun2()
{
	int a;
	a = 10;
	return a;
}
int *fun3()
{
	int a;
	a = 10;
	return &a;
}
int main()
{
	int a = fun1();//函数1调用完成后内存空间被析构,返回10,将这个值一般情况下放在寄存器中,在拿给a。

	int b = fun2();//用变量取接返回的引用,函数2调用完成后返回内存的本身,
	                  //即在栈中给a开辟的空间的副本,值是10,
	                //  如果你用变量去接它把10就扔给b没有问题。
	           
	int &c = fun2();//用引用去接引用,相当于接住了返回回来的空间地址,
	printf("%d  %d  %d", a, b, c);//在打印的时候编译器发现c是一个引用,于是就替换成*c,
	                             //但是这块内存空间被清空了,所以*c找到的可能是乱码。
	getchar();
	return 0;
}
输出a,b正常,c不确定。

  //若返回全局变量或者静态变量的话,便可以为其他引用的初始值,即可以做右值,也可以做左值

int &fun()
{
	static int a = 10;//静态变量的话
	a++;
	return a;
}
int main()
{
	int &b = fun();//完全可以没有任何问题
	return 0;
}
下面演示一下函数当左值

int &fun()
{
	static int a = 10;
	a++;
	return a;
}
int main()
{
	 fun()=10;//函数当左值没有任何问题
	return 0;
}
8.指针的引用


9.常引用

//1.使用变量初始化const常引用

//2.使用字面量常量初始化const常引用

1.用变量区=去初始化

int a=10;
const int &b=a;//常引用,其作用是让变量a具有可读性,不能通过b去修改a的值
2.用常量去初始化

int &m=10;
这样合法吗?

答:不合法,因为10这个字面量没有内存空间无法引用,因为引用就是给内存空间起别名。

怎么使它合法呢?

const int  &m=10;

这样就合法了

,有个问题:const  int  &m=10开辟内存吗?

我的理解是:const int &m=10;编译器这么理解int no_name=10;   const int &m=no_name;这个no_name是无形的你不可见,编译器自己做了这个工作使这句话通过











 












  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值