bosthhe1 / cpushpush

0 stars 0 forks source link

引用的初始 #2

Open bosthhe1 opened 2 years ago

bosthhe1 commented 2 years ago

引用的本质,就是对变量取别名,不占用额外空间,但是底层还是一个指针,而且是指针常量,但是我们在使用的过程中就看作取别名来使用,不必深究(在使用引用的过程中,我们写的是int a = 10;int &b = a;编译器会自动将int &b = a编译成int const b = &a;所以本质上还是对接的地址,这里是不能修改b的指向,所以能看出b只能初始化一次,不过b的值可以修改)(修改b的值,b = 20;编译器会自动转变为b = 20(这里也可以看出时对地址的引用)) 指针的引用 用一级指针引用 可以代替二级指针(如传一级指针的地址,可以用二级指针接受,也可以用引用来接受 (DateB(&p);调用函数传指针p的地址) (void DateB(int *p); 这是二级指针接受) (void DateB(int &p);这是引用接受))

bosthhe1 commented 2 years ago

常量引用 在c++中引用必须初始化变量,不能初始化常量,因为引用时取得地址,所以引用常量会报错 但是可以写成const int &a = 10;这样的话,编译器会自动生成一个临时变量(tmp),将临时变量tmp赋予10, 然后将const int &a=tmp;

bosthhe1 commented 1 year ago

对于引用需要注意的是,我们可以权限缩小,相等,但是不能放大,如 const int a =10; (错)int &b = 0;//这里造成了权限放大,a是本身不可以修改的,b如果引用了a,b也必须和a一致不能修改 (对)const int&b = 0; // int a =10; int &b =a;//权限不变,可读可写 // int a= 10; const int & b =a;//权限缩小,只可读不可写 // // 意识到权限后我们需要注意的另外一个点就是引用在引用临时变量(常性的变量(常性的意思是不可对其修改))(在如传参,类型转换的时候都会产生临时变量,都不可对其修改)(临时变量又叫做右值) 我们在c语言知道,当类型不同的赋值的时候,会进行强制类型转换如 double a = 1.11; int b = a;//此时会将a的类型产生一个临时变量 1 (这个临时变量具有常性,不可修改)赋予给b (错)int & b =a;//因为零时变量具有常性,所以临时变量不具有修改的权限(所有产生的临时变量都具有常性,不可修改) (对)const int & b = a;//这里b引用的不是a,是a产生的临时变量 这要是通过计算过后的值,都是临时变量,而临时变量具有常性 image 加上const就不会报错 image 对于权限问题,只要是指针都需要注意

bosthhe1 commented 1 year ago

我们需要注意的是当引用作为返回值的时候,是返回当时值的地址,但是函数调用完成后,出了函数栈帧,函数会被销毁,编译器就会回收这个空间,那么这个引用就成了非法访问,但是在堆上开辟的空间不会非法访问,因为堆上开辟的空间,是需要主动释放的,不随函数结束而销毁。 可以看出vs2013版本,栈帧销毁了,编译器没回收数据,所以第一次可以打印成功,但是当我们调用printf函数的时候,就将那个地址的值改了,所以第二次打印是随机值 image

bosthhe1 commented 1 year ago

虽然引用底层是指针,但是不能深究底层,我们看到b是a的引用,但是b的字节大小为1,说明b是a的别名,和a一样 image

bosthhe1 commented 1 year ago

引用再定义的时候就必须初始化,且引用只能初始化一次