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的值赋给bcout<<"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
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;
}