C++基础(九)-引用
来源:互联网 发布:python高维数据可视化 编辑:程序博客网 时间:2024/06/15 12:42
1. 引用概念
c++中新增了引用的概念,引用可以作为一个已定义变量的别名。引用是c++对c的重要扩充。在c/c++中指针的作用基本都是一样的,但是c++增加了另外一种给函数传递地址的途径,这就是按引用传递(pass-by-reference),它也存在于其他一些编程语言中,并不是c++的发明。
1. 变量名实质上是一段连续内存空间的别名,是一个标号(门牌号)
2. 程序中通过变量来申请并命名内存空间
3. 通过变量的名字可以使用存储空间
基本语法:
Type& ref = val;
注意事项:
1. &在此不是求地址运算,而是起标识作用。
2. 类型标识符是指目标变量的类型
3. 必须在声明引用变量时进行初始化。
4. 引用初始化之后不能改变。
5. 不能有NULL引用。必须确保引用是和一块合法的存储单元关联。
6. 建立对数组的引用。
//1. 认识引用void test01(){ int a = 10; //给变量a取一个别名b int& b = a; //int * const b = &a; cout << "a:" << a << endl; cout << "b:" << b << endl; cout << "------------" << endl; //操作b就相当于操作a本身 b = 100; cout << "a:" << a << endl; cout << "b:" << b << endl; cout << "------------" << endl; //一个变量可以有n个别名 int& c = a; c = 200; cout << "a:" << a << endl; cout << "b:" << b << endl; cout << "c:" << c << endl; cout << "------------" << endl; //a,b,c的地址都是相同的 cout << "a:" << &a << endl; cout << "b:" << &b << endl; cout << "c:" << &c << endl;}//2. 使用引用注意事项void test02(){ //1) 引用必须初始化 //int& ref; //报错:必须初始化引用 //2) 引用一旦初始化,不能改变引用 int a = 10; int b = 20; int& ref = a; ref = b; //不能改变引用}
建立数组引用:
//1. 建立数组引用方法一 typedef int ArrRef[10]; int arr[10]; ArrRef& aRef = arr; for (int i = 0; i < 10;i ++){ aRef[i] = i+1; } for (int i = 0; i < 10;i++){ cout << arr[i] << " "; } cout << endl; //2. 建立数组引用方法二 int(&f)[10] = arr; for (int i = 0; i < 10; i++){ f[i] = i+10; } for (int i = 0; i < 10; i++){ cout << arr[i] << " "; } cout << endl;
2. 指针引用
Type* pointer = NULL; Type*& = pointer;
例子:
struct Teacher{ int mAge;};//指针间接修改teacher的年龄void AllocateAndInitByPointer(Teacher** teacher){ *teacher = (Teacher*)malloc(sizeof(Teacher)); (*teacher)->mAge = 200; }//引用修改teacher年龄void AllocateAndInitByReference(Teacher*& teacher){ teacher->mAge = 300;}void test(){ //创建Teacher Teacher* teacher = NULL; //指针间接赋值 AllocateAndInitByPointer(&teacher); cout << "AllocateAndInitByPointer:" << teacher->mAge << endl; //引用赋值,将teacher本身传到ChangeAgeByReference函数中 AllocateAndInitByReference(teacher); cout << "AllocateAndInitByReference:" << teacher->mAge << endl; free(teacher);}
对于c++中的定义那个,语法清晰多了。函数参数变成指针的引用,用不着取得指针的地址。
3. 常量引用
常量引用的定义格式:
const Type& ref = val;常量引用注意:
1. 字面量不能赋给引用,但是可以赋给const引用
2. const修饰的引用,不能修改。
void test01(){ int a = 100; const int& aRef = a; //此时aRef就是a //aRef = 200; 不能通过aRef的值 a = 100; //OK cout << "a:" << a << endl; cout << "aRef:" << aRef << endl;}void test02(){ //不能把一个字面量赋给引用 //int& ref = 100; //但是可以把一个字面量赋给常引用 const int& ref = 100; //int temp = 200; const int& ret = temp;}
4. 引用是什么?
C++标准只规定了引用的语义,并没有规定引用如何实现。在大部分编译器中引用在C++内部是通过常量指针来实现,因此引用所占空间大小与指针大小相同,只是这个过程由编译器内部实现,对用户不可见。
//发现是引用,转换为 int* const ref = &a;void testFunc(int& ref){ ref = 100; // ref是引用,转换为*ref = 100}int main(){ int a = 10; int& aRef = a; //自动转换为int* const aRef = &a;这也能说明引用为什么必须初始化 aRef = 20; //内部发现aRef是引用,自动帮我们转换为: *aRef = 20; cout << "a:" << a << endl; cout << "aRef:" << aRef << endl; testFunc(a); return EXIT_SUCCESS;}
5. 引用优点
1. 引用不产生新的变量,减少形参与实参传递时的开销;
2. 由于引用可能导致实参随形参改变而改变,将其定义为常量引用可以消除这种副作用;
3. 不存在空值的引用,意味着我们在使用引用的时候不需要判断是否为NULL,一定程度上提升了效率;
4. 引用传递的性质像是指针传递,但是书写方式像值传递,引用的语法要比指针的语法更加易读和操作,指针能做的事情,引用也能做
了解: 在什么情况下使用指针,在什么情况下使用引用呢?
考虑到存在不指向任何对象的情况下;
可能在不同的情况下指向不同的对象,那么应该使用指针;
如果总是指向一个对象,且一旦初始化不会改变指向,那么应该用引用。
C++主张用引用传递取代地址传递的方式,因为引用语法容易且不易出错
很多同学可能有疑问,为什么C++中有了指针这种操作,还要提供引用。那么原因是C++为了兼容C语言,所以在C++中保留了C语言的指针,那引用是为了什么?在C++中支持运算符重载,那么引用设计的初衷是为了支持运算符重载。有些运算符在有些情况下不得不使用引用。一般情况下,指针和引用是可以直接互换的。
6. 什么时候使用引用
最常见看见引用的地方是在函数参数和返回值中。如果从函数中返回一个引用,必须像从函数中返回一个指针一样对待。当函数返回值时,引用关联的内存一定要存在。
引用作为其它变量的别名而存在,因此在一些场合可以代替指针。
1. 不能返回局部变量的引用。
2. 函数当左值,必须返回引用。
//返回局部变量引用int& TestFun01(){ int a = 10; //局部变量 return a;}//返回静态变量引用int& TestFunc02(){ static int a = 20; cout << "static int a : " << a << endl; return a;}int main(){ //不能返回局部变量的引用 int& ret01 = TestFun01(); //如果函数做左值,那么必须返回引用 TestFunc02(); TestFunc02() = 100; TestFunc02(); return EXIT_SUCCESS;}
如果希望实参随着形参的改变而改变,那么使用一般的引用,如果不希望实参随着形参改变,那么使用常引用。
//const int& param防止函数中意外修改数据void ShowVal(constint& param){ cout << "param:" << param << endl;}
- C++基础(九)-引用
- javascript基础九(知识点类对象的引用)
- 黑马程序员-C语言基础九:指针
- C语言基础(九)- 链表
- 黑马程序员-iOS基础-Objective-C基础(九)
- objective-c基础之引用计数
- 【C++】C++基础:指针__引用__const
- 九、c++的引用
- c/c++基础(九) auto, static , register , extern 区别
- 黑马程序员——Object-C基础(九)内存管理
- Objective-C基础学习笔记(九)-Foundation
- 零基础学C语言 笔记九 字符串
- C语言基础(九)结构体、补充typedef用法
- c语言基础(九)结构体指针
- Objective-C(基础篇)九大基本类型
- C/C++中关于地址、指针和引用变量的学习笔记(九) : 内存结构
- 【Objective-C高级编程】iOS与OS X多线程和内存管理(九) Block 循环引用
- (c/c++学习笔记九)引用传递、指针传递和值传递
- CentOS7 64位下MySQL5.7安装与配置(YUM)
- java开发规范:效率与避免问题
- 如何深入和高效的学习编程语言
- LeetCode编程练习
- 遗传算法基本原理及在互联网中的应用
- C++基础(九)-引用
- 历届试题 PREV-6 翻硬币
- (二)ARM的汇编指令
- 历届试题 PREV-7 连号区间数
- MQL5-日期时间型和颜色型
- dedecms后台"所有档案列表"和"等待审核的档案"重叠的解决方法
- 【ccf-201412-1】门禁系统
- LeetCode编程练习
- 用CSS开启硬件加速来提高网站性能