C++中函数参数*&与&的区别:原理、性能及选用建议
*&指针引用与普通引用的解析 首先直接给你拆解:char* &str1 这玩意儿是指向char的指针的引用,可以理解成给一个指针变量起了个别名。和你学的普通&(比如char &str1,字符的引用)本质都是引用,但作用的对象完全不同——一个作用在指针变量本身,一个作用在普通变量(或对象)上。
工作原理差异
1. 普通引用T &(比如char &str)
这是对T类型变量的直接引用,相当于原变量的"别名"。比如你第二个swap函数:
void swap(char &str1, char &str2) { char temp = str1; str1 = str2; str2 = temp; }
调用时传两个char变量,函数里操作str1、str2就是直接修改原变量的值,底层编译器通常会用指针实现,但语法上完全不用你管指针那套,更安全(引用必须初始化,不能为null)。
2. 指针引用T* &(比如char* &str)
这是对T*类型变量(也就是指针变量)的引用。比如你第一个swap函数,它的作用是修改指针变量本身的指向,而不是指针指向的内容。这里要提一句:你的原代码其实有编译错误,因为char* &不能绑定到const char*(权限被非法放大了),得把swap的参数改成const char* &才能正常运行。修正后调用swap(str1, str2),函数里交换的是str1和str2这两个指针变量的指向——原来str1指向"GEEKS",交换后指向"FOR GEEKS",反之亦然。
如果不用指针引用,而是直接传char*(值传递),那swap函数里修改的只是形参指针,实参的指针指向根本不会变,这就是为什么要用到指针引用的核心原因:要在函数内部修改外部指针变量的指向。
性能差异
说实话,两者性能几乎没有区别。因为C++里的引用底层几乎都是用指针实现的,不管是普通引用还是指针引用,都是一次间接访问。哪怕是极端性能敏感的场景,这点差异也可以完全忽略——重点从来不是性能,而是语义和用途。
实际开发中的选择原则
- 当你需要修改普通变量/对象的值,或者想避免拷贝大对象(比如自定义类对象)时,用普通引用
T &。比如交换两个int、char,或者传递一个大的std::string对象给函数,用引用避免拷贝。 - 当你需要修改指针变量的指向,或者需要传递指针同时不想拷贝指针(虽然指针本身拷贝成本极低,但引用更符合"操作原变量"的语义)时,用指针引用
T* &。比如你想写一个函数,把外部的指针重新分配内存指向新的缓冲区,或者像你例子里这样交换两个指针的指向,就必须用指针引用。
内容的提问来源于stack exchange,提问作者Phineas

