前言:c++基础中,const和引用,经常在函数参数,函数返回值类型中出现。因此必须拿下引用的用法!
目录
一 引用(普通引用)
引用分为:普通引用和常引用;
引用的实质: 一段连续存储空间的别名;使用引用必须初始化!
1常量的引用:
int a=10;
int &b=a; //int * const b =&a;
b =100;//*b =100;
1.引用做函数参数:
复杂数据类型的引用:
请注意三个函数形参的不同:
struct Teacher
{
char name[64];
int age;
};
void printf1(Teacher *pT);
{
cout<<pT->age<<endl;
}
//pT相当于t1的别名,相当于修改了t1
void printfT2(Teacher *pT);
{
pT.age=33;
}
//pT和t1是两个不同的变量
void printfT3(Teacher pT);
{
cout<<pT.age<<endl;
pT.age=45;//只会修改pT变量,不会修改t1
}
int main()
{
Teacher t1;
t1.age=35;
printfT1(&t1);
printfT2(t1); pT是T1的别名;
printfT3(t1);pT是形参,t1copy一份数据,给pT; //--->pT=t1;
return 0;
}
2.引用的本质:
2.1引用的本质:
1c++编译器在定义引用时候背后做了什么工作呢?
单独定义引用时,必须初始化,说明很像一个常量;
2引用有自己的内存空间吗?
答: 引用 和 引用的对象占内存空间大小一样 ;公用同一内存空间;a,b就是同一块内存空间的门牌号;
32位,内存指针占4位。64位内存指针占8位;
因此!
1)引用在c++中内部是一个常指针:
Typer & name <---->Type * const name;
2) c++编译器使用常指针作为引用内部实现
3)从使用角度,引用会让人误会成时一个别名,没有自己的存储空间,这是c++为实用性做出的细节隐藏;
void func(int &a) void func (int *const a)
{a=5; { *a=5;
} }
4)请对比指针间接赋值成立三个条件:(间接赋值是指针存在的最大意义)
a)2个变量,(一个实参,一个形参)
b)建立关系,实参去抵制给形参指针;
c)*p形参去间接修改实参的值;用在接口的封装和设计;
传参的时候:func(a) fun (&a) func (&a)
2.2引用的意义:
1引用作为变量的别名,在某些地方可以替代指针;
2引用可读性,实用性增强,更加简洁;
2.3引用的结论:
1)引用在实现上,只不过是把,间接赋值成立的三个条件的后两步和二唯一;
函数调用时,c++编译器帮我们取一个函数地址,我们不需要取实参的地址,
2)当我们使用引用语法时,不去关心编译器引用是怎么做的,
当我们分析奇怪语法现象时,我们才去考虑c++编译器是这么做的;
3.引用当左值:
若函数返回值为引用时(引用使用的难点):
1若返回栈的变量:
不能成为其它引用的初始值,不能作为左值使用;
2若返回静态变量or全局变量时:
可以成为其它引用的初始值,可以是左值,也可以是右值;
第一种情况:get1,&get2中 a是临时变量,函数结束自动销毁;返回的内存可能不存在;不能当左值;
第二种情况:
我们把上面局部变量的a变成静态变量,测试就可以通过;a1=11;a2=11;a3=12;说明返回的内存不被销毁时,则可以使用!
同样的,我们再看一下函数返回值作左值!也是可以成立的!
此外,c++链式编程,经常用到引用,运算符重载也会用到引用;
4.指针引用:
(指针只向谁,就把谁的地址赋值给指针;)
我们先复习一下二级指针:(以下为核心代码)
strcut Teacher
{
char name[64];
int age;
}
void getTeacher (Teacher **p)//在被调用函数,获取内存资源
{
Teahcer *tep=NULL;
tmp= (Teacher *)malloc (sizeof(Teacher));
*p=tmp;
}
int main()
{
Teacher *pT1=NULL;
getTeacher (&pT1);
return 0;
}
让我们再来看看引用:引用的本质(间接赋值后的2个条件,让c++编译器帮我们做了);
int getTeacher2(Teacher* &myp)
{myp=(Teacher *)malloc (sizeof(Teacher));//给myp赋值相当于给main函数pT1赋值;
}
int main()
{
getTeacher2(pT1);
}
二.常引用:
普通引用:
int m = 5
int &n=m;
而常引用 初始化分两种:
1用变量 初始化 常引用 2使用字面量 初始化 常引用
4.1使用变量 初始化const引用:
int x=20;
const int &y =x;
//y=21; //常引用 是 让变量 只读属性,不能通过y去修改x了;作用在传函数参数时使用;
在函数传参数时使用:
void fun(const int &myt);{//myt 不能改变 }//常引用 让实参变量 拥有只读属性;
void fun(const int * const p);
4.2使用字面量 初始化const引用:
const int a=40; //c++编译器把a放在符号表中了;
//int &m=41; //普通引用,41没有内存的值;引用就是给内存取别名;
const int &m =42;//c++编译器会 m分配一个内存空间;让m指针只向42的内存空间
结论:
1.const & e 相当于 const int* const
2.普通引用相当于 int * const e1
3.当常量(字面量)对const 进行初始化的时候,c++会为常量值分配内存空间;并将引用名字作为这段空间的别名;
4使用字面量const引用初始化后,将生成一个只读变量;