引用相关知识介绍

文章介绍了C++中的引用概念,作为已存在变量的别名,必须在定义时初始化。引用用于做输出型参数和返回值,可以提高效率。const引用用于只读访问,提高了代码的可读性和安全性。文章通过示例代码展示了引用在函数参数和返回值中的应用,并强调了const引用的权限和使用场景。

1、引用的概念与特性`

#include "SeqList.h"

int main()
{
	// 1、引用的概念(给已存在的变量取别名)
	int a = 0;
	int& b = a; //给变量a取别名为:b

	cout<< &a <<endl; //取a地址
	cout<< &b <<endl; //取b地址
	a++;
	b++;

	// 2、引用的特性
	int a = 1;
	int& b = a; //A\ 引用在定义时必须初始化。

	int& b = a; //B\ 一个变量可以有多个引用(别名)
	int& c = a;
	int& d = c;
	a++;

	int x = 10; 
	b = x;  //这里是将x赋值给b
  // C\ 引用一旦引用一个实体,再不能引用其他实体。
	return 0;
}

2、引用的用途

2.1 做输出型参数

// (1)做输出型参数

//例1 Swap交换
void Swap(int& r1,int& r2)
{
	int tmp = r1;
	r1 = r2;
	r2 = tmp;
}

int main()
{
	int a = 0;
	int b = 2;
	Swap(a,b);

	return 0;
}

//例2 顺序表
typedef struct SeqList 
{
	//.....
}SL;

void SLPushBack(SL& s,int x) //SL& s=sl; 这里的s是sl的别名,这里的形参是实参的别名,进而导致形参改变,影响到了实参。
{
	//.....
}

int main()
{
	SL sl;
	SLPushBack(sl,1);
	SLPushBack(sl, 2);
	SLPushBack(sl, 3);

	return 0;
}

//例3、单链表
typedef struct SListNode
{
	//.......
}SLTNode,*PSLTNode; //*PSLTNode的意思为:typedef SLTNode* PSLTNode; 

//void SListPushBack(SLTNode** pphead, int x) //这里用二级指针接收
//void SListPushBack(SLTNode*& phead, int x) //这里用指针变量的引用(别名)接收
void SListPushBack(PSLTNode& phead, int x)  //PSLTNode 相当于 SLTNode*
{
//......
}

int main()
{
	SLTNode* list;
	//SListPushBack(&list,1);
	//SListPushBack(list, 2);
	SListPushBack(list, 3);

	return 0;
}

2.2 做输出型返回值

2.2.1 做输出型返回值的条件

应用条件:如果出了函数的作用域,返回对象就销毁了,那么一定不能用引用返回,一定要用传值返回。

//(1)传引用返回(返回的是:返回对象的别名)
int& Count()
{
    int n = 0; //(有static时,出了函数Count的作用域,n在静态区内且未销毁,可以用传引用返回)
	n++;              //(没有static时,n在栈区内,出了函数Count的作用域,n就销毁了,无法用传引用返回)
	return n;  //这里返回的是:返回对象n的别名(假设为tmp; int& tmp=n;)
}       

int main()
{                      // int ret=tmp;[tmp是n这块空间的别名]
	int ret = Count(); //ret的结果是随机的。如果栈帧结束,系统会销毁栈帧置成随机值,那么这里ret的结果就是随机值。
	cout << ret << endl;
	cout << ret << endl;
	
	return 0;
}


//(2)额外补充:传值返回(返回的是:返回对象值的临时拷贝)
int Count()
{
	int n = 0;//(没有static时,n在栈区内)(有static时,n在静态区内)
	n++;
	return n;
}

int main()
{
	int ret = Count();
	cout<< ret <<endl;
	return 0;
}


2.2.2 具体应用

Test.cpp

#include "SeqList.h"
int main()
{
	SL sl;
	SLInit(sl);
	SLPushBack(sl,1);
	SLPushBack(sl, 2);
	SLPushBack(sl, 3);
	SLPushBack(sl, 4);
	
	for (int i=0;i<sl.size;i++)
	{
		cout<< SLAt(sl,i) <<" ";
    }
	cout << endl;
//引用做返回值,既可以直接打印,也可以直接修改
//SLAt(sl,i)的返回值是返回对象s.a[pos]的别名;出了函数SLAt的作用域,s.a[pos]只是名字没了,实际数组没有销毁,因为数组是开辟在堆区上的。
	SLAt(sl,0)++;
	SLAt(sl,2) = 10;

	for (int i = 0; i < sl.size; i++)
	{
		cout << SLAt(sl, i) << " ";
	}
	cout << endl;

	return 0;
}

SeqList.h

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
using namespace std;


typedef struct SeqList
{
	int* a;
	int size;
	int capacity;
}SL;

void SLInit(SL& s, int capacity = 4);
void SLPushBack(SL& s, int x);

//修改顺序表数据的函数
//void SLModify(SL& s,int pos,int x);
int& SLAt(SL& s,int pos);

SeqList.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void SLInit(SL& s, int capacity)
{
	s.a = (int*)malloc(sizeof(int)*capacity);
	assert(s.a);
	s.size = 0;
	s.capacity = capacity;
}

void SLPushBack(SL& s, int x)
{
	if (s.size==s.capacity)
	{
        //......
     }
	s.a[s.size] = x;
	s.size++;
}

int& SLAt(SL& s, int pos)
{
	assert(pos>=0 && pos<s.size);

	return s.a[pos];
}

2.3 做输出型参数或输出型返回值时,均能提高效率

3、const引用

3.1 const引用权限

int main()
{
	//4.1 const引用权限
	//引用权限平移
	int a = 2;
	int& b = a;
	cout<< typeid(a).name() <<endl;
	cout << typeid(b).name() << endl;

	//引用权限放大(不行)
	const int c = 1;
	//int& d = c;
	const int& d = c;
	
	//引用权限缩小
	int e = 4;
	const int& f = e;

	//权限的平移例子:
	int ii = 2;
	//double& rdd = ii;
	const double& rdd = ii;
	// 中间产生一个 const double类型的临时变量:tmp
	const int& x = 10;

	return 0;
}

3.2 const引用的应用

void func(const int& n) //如果使用 引用传参,且函数内不改变n,则建议尽量用const引用传参。(因为const引用传参的接受度很高)
{
}

int main()
{
	int a = 2;
	const int b = 3;
	func(a);
	func(b);
	func(10);

	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值