
文章目录一、基础概念二、引用的特性1. 引用是别名2. 引用必须初始化3. 引用不能重新绑定4. 引用没有独立的内存地址三、使用场景1. 函数参数传递2. 函数返回值3. 避免大对象拷贝四、传值 vs 传引用的效率对比传值传引用效率对比示例五、常引用常引用的优势六、权限放大、缩小、不变1. 权限不变推荐2. 权限缩小允许3. 权限放大不允许函数参数中的权限规则七、引用 vs 指针相似点主要区别代码对比使用建议总结首先列出一下csdn 引用的经典文章csdn引用理解这篇文章讲的非常好。然后我们开始本文讲解我来为你详细讲解C的引用从基础概念到高级特性。一、基础概念**引用Reference**是C中的一种复合类型它是某个已存在变量的别名。引用不占用额外的存储空间它只是目标变量的另一个名字。inta10;intrefa;// ref是a的引用即a的别名关键点引用必须在声明时初始化引用一旦初始化就不能重新绑定到其他变量引用必须引用有效的对象不能是NULL二、引用的特性1. 引用是别名intx5;intrefx;ref10;// 修改ref就是修改xx现在也是102. 引用必须初始化intref;// 错误引用必须初始化inta5;intrefa;// 正确3. 引用不能重新绑定inta5,b10;intrefa;refb;// 这不是重新绑定而是将b的值赋给a4. 引用没有独立的内存地址inta5;intrefa;coutaendl;// 输出相同的地址coutrefendl;// 输出相同的地址三、使用场景1. 函数参数传递voidswap(inta,intb){inttempa;ab;btemp;}intmain(){intx5,y10;swap(x,y);// x和y的值会被交换}2. 函数返回值intgetElement(intarr[],intindex){returnarr[index];// 返回引用可以修改数组元素}intmain(){intarr[5]{1,2,3,4,5};getElement(arr,2)100;// 修改arr[2]为100}3. 避免大对象拷贝structBigData{intdata[1000];};voidprocess(constBigDatadata){// 使用引用避免拷贝大对象}四、传值 vs 传引用的效率对比传值voidfunc(intx){xx1;}intmain(){inta5;func(a);// a的值不变因为传递的是副本}特点会创建参数的副本对于基本类型int, char等效率差异不大对于大对象结构体、类对象会有明显的性能开销传引用voidfunc(intx){xx1;}intmain(){inta5;func(a);// a的值会改变}特点不创建副本直接操作原对象对于基本类型效率提升不明显对于大对象效率提升显著效率对比示例#includeiostream#includechronostructLargeStruct{intdata[10000];};voidbyValue(LargeStruct s){s.data[0]1;}voidbyReference(LargeStructs){s.data[0]1;}intmain(){LargeStruct obj;autostart1std::chrono::high_resolution_clock::now();for(inti0;i10000;i){byValue(obj);}autoend1std::chrono::high_resolution_clock::now();autostart2std::chrono::high_resolution_clock::now();for(inti0;i10000;i){byReference(obj);}autoend2std::chrono::high_resolution_clock::now();// 传引用会明显快于传值}五、常引用常引用用于防止通过引用修改被引用的对象voidprintValue(constintref){coutrefendl;// ref 10; // 错误不能通过常引用修改值}intmain(){inta5;printValue(a);// 可以传递printValue(10);// 也可以传递临时对象}常引用的优势防止意外修改可以接受临时对象右值提高代码安全性六、权限放大、缩小、不变1. 权限不变推荐inta10;intrefa;// 权限不变可变→可变constintcrefa;// 权限缩小可变→不可变constintb20;constintcref2b;// 权限不变不可变→不可变2. 权限缩小允许inta10;constintrefa;// 允许从可变到不可变3. 权限放大不允许constinta10;intrefa;// 错误不能从不可变到可变函数参数中的权限规则voidfunc1(intref){// 需要可变引用}voidfunc2(constintref){// 可以接受可变和不可变引用}intmain(){inta10;constintb20;func1(a);// 正确func1(b);// 错误权限放大func2(a);// 正确func2(b);// 正确}七、引用 vs 指针相似点都可以用来间接访问对象都可以作为函数参数传递主要区别特性引用指针初始化必须初始化可以不初始化重新绑定不能重新绑定可以重新指向其他对象空值不能为NULL可以为nullptr内存占用通常不占用额外内存占用指针大小的内存运算符使用声明直接使用使用*声明和解引用语法int ref a;int* ptr a;代码对比// 引用inta10;intrefa;ref20;// 直接使用// 指针inta10;int*ptra;*ptr20;// 需要解引用// 指针可以重新指向intb30;ptrb;// 正确// 引用不能重新绑定intref2a;ref2b;// 这是赋值不是重新绑定使用建议使用引用的情况参数传递特别是大对象函数返回值确定总是有效的情况需要简洁语法时使用指针的情况需要重新绑定需要表示无值nullptr需要指针运算实现数据结构链表、树等总结引用是C中强大的特性它提供了高效的参数传递机制简洁的语法更好的代码安全性配合const使用理解引用的特性、权限规则以及与指针的区别对于编写高效、安全的C代码至关重要。在实际开发中优先使用引用特别是const引用来传递参数可以显著提高代码的效率和可读性。