引用是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是无形的你不可见,编译器自己做了这个工作使这句话通过