引用类型
“引用”(reference)是c++的一种新的变量类型,是对C的一个重要补充。它的作用是为变量起一个别名。假如有一个变量a,想给它起一个别名,可以这样写:
int a;
int &b=a;
这就表明了b是a的“引用”,即a的别名。经过这样的声明,使用a或b的作用相同,都代表同一变量。在上述引用中,&是“引用声明符”,并不代表地址。
不要理解为“把a的值赋给b的地址”。声明引用并不开辟内存单元,b和a都代表同一变量单元。
注意:在声明引用变量类型时,必须同时使之初始化,即声明它代表哪一变量。在声明一个变量的引用之后,在本函数执行期间,该引用一直与其代表的变量相联系,不能再作为其他变量的别名。下面的用法不对:
int a1,a2;
int &b=a1;
int &b=a2;//企图使b变成a2的别名(引用)是不行的。这样是错误的。但可以把a2的值赋给b:b=a2;
一、学习
二、边学边练
1、C++引用篇
三、引用(reference)学习文章
1.概念
引用是C++对C的一个重要扩充,引用表示给变量起个别名;//类似于linux中的硬链接文件
2.定义引用
数据类型 &引用名 = 引用的目标;
如: int &b = a;
& 在C++有三种作用:
(1)定义引用时,是引用标识符,表示定义的是一个引用
(2)按位与 &
(3)其他任何场景下,都代表取地址的意思
3.使用使用的要求
(1)定义引用时,要求必须初始化;
//int &b;//错误的
(2)引用一旦指定了引用的目标,就不可以再改变了;
(3)引用的类型和引用目标的类型要保持一致;(继承时除外)
4.引用的基本使用
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
int a = 100;
int &b = a;
b = 200;
cout<<"a = "<<a<<" b = "<<b<<endl;
cout<<"&a = "<<&a<<" &b"<<&b<<endl;
return 0;
}
5.异常使用场景验证
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
int a = 100;
int a2 = 50;
//int &b;//b没有初始化,会报错
int &b = a;
b = a2;//此处不是改变引用目标,而是将a2的值赋给b
cout<<"a = "<<a<<" b = "<<b<<endl;
cout<<"&a = "<<&a<<" &b"<<&b<<endl;
return 0;
}
6.引用做形参
好处:不用考虑值传递地址传递的问题了
#include <iostream>
using namespace std;
void my_add(int ∑, int a, int b){
sum = a+b;
cout<<"func---"<<∑<<endl;//和下面相同
}
int main(int argc, const char *argv[])
{
int a = 100;
int b = 200;
int sum = 0;
my_add(sum, a, b);
cout<<sum<<endl;
cout<<"main---"<<∑<<endl;//和上面相同
return 0;
}
7.引用指针的写法
#include <iostream>
#include <cstdlib>
using namespace std;
void func(int * &p){
p = (int *)malloc(4);
*p = 100;
}
int main(int argc, const char *argv[])
{
int *p = NULL;
func(p);
cout<<*p<<endl;
return 0;
}
8.常引用
const
(1)保护形参不被修改
(2)可以引用常量
#include <iostream>
#include <cstdlib>
using namespace std;
//有些场景下,函数中不想修改形参的值
//可以使用 常引用
void func(const int &r){
//r = 200;//错误的
}
int main(int argc, const char *argv[])
{
int a = 100;
func(a);
const int &r2 = 200;//可以引用常量
return 0;
}
左值右值:
右值:只能放在等号右边的值,如 100 "hello" 'c' a+b 等
左值:即能放在等号左边,又能放在等号右边的值 b = a , a = 10
9.结构体中定义引用
#include <iostream>
using namespace std;
struct Test{
int a;
int &b;
};
int main(int argc, const char *argv[])
{
int m = 100;
Test t1 = {10,m};//结构体中有引用成员时,
//要求定义这个结构体的变量时必须初始化
return 0;
}
10.引用和指针的区别
引用与指针区别
(1)引用必须初始化 指针可以不初始化
(2)引用不可以改变指向 指针可以
(3)不存在指向NULL的引用 指针可以指向NULL
(4)指针在使用前需要检查合法性 引用不需要
(5)可以定义指针数组、不可以定义引用数组
int a = 10,b = 20;
int *arr[2] = {&a, &b} //正确
------------------------------------
int &arr[2] = {a, b} //错误
(6)可以定义数组指针,也可以定义数组引用
(但是有点区别:数组引用不能指向二维数组,如下例子)
int arr[2][2] = {10,20,30,40};
int (*arr_p)[2] = arr;
-----------------------------------
int arr[2] = {10,20};
int (&arr_p)[2] = arr;//错误的数组引用
int (&arr_p)[2][2] = arr;//正确的数组引用
(7)可以定义指针函数,也可以定义引用函数
int *func_p(int a, int b){}
-----------------------------------
int &func_p(int a, int b){}
(8)可以定义函数指针,也可以定义函数引用
int func(int a, int b){}
int (*func_p)(int a, int b);
func_p = func;
------------------------------------
int (&func_r)(int a, int b) = func;
(9)可以定义指针的指针(二级指针) 不可以定义引用的引用(二级引用)
int a = 100;
int *p = &a;
int **pp = &p;
---------------------------------
int a= 100;
int &r = a;
int &&rr = r; //错误
int &&r = 100; // 可以 叫做右值引用,
C++11以上版本的编译器才支持这种用法
11.引用做返回值
(1)不能返回局部变量的引用
(2)可以返回全局变量的引用,或者static修饰的局部变量的引用
(3)引用作为返回值,返回的是一个左值
例:
#include <iostream>
using namespace std;
int &my_add(int a,int b){
//int sum = a+b;//错误的
//return sum;//不能返回局部变量的引用
static int sum = a+b;
return sum;
}
//引用作为返回值时,如果需要防止返回值被修改,
//可以加 const
const int &my_add2(int a,int b){
static int sum = a+b;
return sum;
}
//一种特殊情况
int &my_add3(int a, int b){
return a>b?a:b;//因为编译器认为 a 和 b 在后面会用到
//就不回收资源了
//了解就行---基本不会用到
}
int main(int argc, const char *argv[])
{
int x = 100;
int y = 200;
int ret = my_add(x,y);
cout<<ret<<endl;
//引用作为返回值时,函数的返回值是一个左值,
//后面讲到类 operator= 时再细讲
my_add(x,y) = 100;
//my_add2(x,y) = 100;//带const 不能修改
ret = my_add3(x,y);
cout<<ret<<endl;
return 0;
}

浙公网安备 33010602011771号