我想用函数交换两个变量。我创建了两个函数 my_swap_f1 和 my_swap_f2 ; my_swap_f2 效果很好,但 my_swap_f1 会抛出2个错误(下面已注明)。
#include<iostream>
using namespace std;
int my_swap_f1(int &a,int &b){
int *temp;
temp=&a;
//&a=&b; //throw error
//&b=temp; //throw error
}
int my_swap_f2(int *a,int *b){
//works perfectly
int temp;
temp=*a;
*a=*b;
*b=temp;
}
int main(){
int a=10;
int b=20;
int temp=0;
cout<<"Before Swap"<<endl;
cout<<a<<endl;
cout<<b<<endl;
my_swap_f1(a,b); //send value as perameter
//my_swap_f2(&a,&b); //send address as perameter
cout<<"After Swap"<<endl;
cout<<a<<endl;
cout<<b<<endl;
}
问题:为什么my_swap_f1
中会出现错误?如果我想与my_swap_f1
交换,该怎么办?
答案 0 :(得分:3)
使用引用而不是指针实现swap的主要原因之一是避免代码中的所有*
和&
:
int my_swap_f1(int &a,int &b){
int temp;
temp = a;
a = b; // a/b refer to the parameters that were passed
b = temp; // modifying a reference is the same as modifiying the original
}
那一行:
&a = &b;
无效,因为&a
(a
的地址)是右值。对于你不能分配的东西来说,rvalue是马虎的,它只能出现在作业的右侧。如果它有效,则意味着:&#34;取a
的地址并将其设置为b
&#34;的地址,但当然不能更改对象的地址像那样。
答案 1 :(得分:1)
my_swap_f1
和my_swap_f2
之间的区别在于my_swap_f2
声明其参数为指针类型,而my_swap_f1
声明其参数为参考类型。引用的工作方式与C ++中的指针不同,并且您试图在my_swap_f1
中错误地使用引用。
在C ++中,引用类型是一个不可变指针式句柄,它只指向引用类型的一个实例,永远不能重新分配。在大多数表达式中,它被视为引用类型的值,这意味着您可以直接访问引用的实例&#34;&#34;没有取消引用任何东西。因此,如果您声明引用变量int &a
,则引用a
只指向一个int
,您只需编写即可访问int
的值a
,例如在作业int temp = a
中(请注意temp
只是int
,而不是参考)。没有必要写&a
,这样做实际上会取int
所指的a
的地址(给你一个指针 - {{1 }),因为&#34;&#34;的地址运算符(int
)将直接应用于&
值。
如果使用&#34;指针修饰符&#34;编写参数声明,这将更有意义。在类型名称旁边而不是变量名称:
int
然后,在实施//This function's parameters are two pointers
int my_swap_f2(int* a, int* b);
//This function's parameters are two references
int my_swap_f1(int& a, int& b);
时,您可以直接分配到my_swap_f1
来更改int
引用的a
值,因为a
是& #34;对a
的引用。&#34;您的函数的正确版本将是:
int
请注意,在第3行中,分配会覆盖void my_swap_f1(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
引用的int
,其a
引用int
的值。引用本身不能更改,因此不需要添加任何额外的符号(如b
)来指示引用的值而不是引用本身。 (另外,我将函数返回类型更改为&
,因为您的代码实际上并未从函数返回值,并且它不需要)。