什么是 值传递,地址传递和引用传递 有什么区别

什么是值传递,地址传递和引用传递?它们有什么不同?这在学校考试,找工作面试中都是常见的问题。它们之间的区别容易搞错,长时间不用也容易忘记。最近又被问到这个问题,想想还是整理一下记下来,也方便以后参考。

首先,看以下三段代码。

1. 

[plain]  view plain  copy




  1. void swap1(int x, int y)    

  2. {  

  3.   int tmp=x;  

  4.   x=y;  

  5.   y=tmp;  

  6.   print(“x=%d, y=%d\n”, x, y);  

  7. }  

  8.   

  9. void main()  

  10. {  

  11.   int a=2,b=7;  

  12.   swap1(a,b) ;  

  13.   printf(“a=%d, b=%d\n”, a, b);  

  14. }  

输出结果是什么?

x=7, y=2

a=2, b=7


2. 

[plain]  view plain  copy




  1. void swap2(int *px, int *py)  

  2. {  

  3.   int tmp=*px;  

  4.   *px=*py;  

  5.   *py=tmp;  

  6.   print(“*px=%d, *py=%d\n”, *px, *py);  

  7. }  

  8.   

  9. void main()  

  10. {  

  11.   int a=2;  

  12.   int b=7;  

  13.   swap2(&a,&b);  

  14.   Print(“a=%d, b=%d\n”, a, b);  

  15. }  

这次输出结果是什么?

*px=7, *py=2

a=7, b=2


3. 

[plain]  view plain  copy




  1. void swap3(int &x, int &y)  

  2. {  

  3.   int tmp=x;  

  4.   x=y;  

  5.   y=tmp;  

  6.   print(“x=%d, y=%d\n”, x, y);  

  7. }  

  8.   

  9. void main()  

  10. {  

  11.   int a=2;  

  12.   int b=7;  

  13.   swap3(a,b);  

  14.   Print(“a=%d, b=%d\n”, a, b);  

  15. }  

那这次输出结果又是什么?


x=7, y=2

a=7, b=2


接下来,分析一下为什么是这样的结果呢?

上面的1,2,3分别是值传递,地址传递,和引用传递。

先看值传递。swap1函数的操作是将x,y进行对调。需要注意的是,对形参的操作不会影响到a,b。我们可以设想,在swap1函数执行语句的最前面,隐含地存在x=a; y=b;这两条语句,这样就便于理解了。当a,b把值赋给x,y之后,对x,y不论再做什么操作,都不会影响到a,b本身。


再看地址传递。注意,这时的函数的声明和调用的写法与值传递不同。

函数声明:swap2(int *px, int *py)

函数调用:swap2(&a, &b)

但是与值传递的分析一样,我们同样可以设想,在swap2函数里,隐含地存在px=&a; py=&b;这两条语句,这表示a的地址代入到了px,b的地址代入到了py。这样一来,对*px, *py的操作就是a,b本身的操作。所以a,b的值被对调了。


接下来看引用传递。先看函数的声明和调用的写法,函数调用和值传递的写法是一样的,但是函数声明是不一样的。

函数声明:swap3(int &x, int &y)

函数调用:swap3(a, b)

因为定义的x,y前面有&取地址符,调用函数swap3时,a,b分别代替了x,y,即x,y分别引用了a,b变量。因此,函数里的操作,实际上是对实参a,b本身的操作,其值发生了对调。


什么是值传递,地址传递和引用传递?它们有什么不同?这在学校考试,找工作面试中都是常见的问题。它们之间的区别容易搞错,长时间不用也容易忘记。最近又被问到这个问题,想想还是整理一下记下来,也方便以后参考。

首先,看以下三段代码。

1. 

[plain]  view plain  copy




  1. void swap1(int x, int y)    

  2. {  

  3.   int tmp=x;  

  4.   x=y;  

  5.   y=tmp;  

  6.   print(“x=%d, y=%d\n”, x, y);  

  7. }  

  8.   

  9. void main()  

  10. {  

  11.   int a=2,b=7;  

  12.   swap1(a,b) ;  

  13.   printf(“a=%d, b=%d\n”, a, b);  

  14. }  

输出结果是什么?

x=7, y=2

a=2, b=7


2. 

[plain]  view plain  copy




  1. void swap2(int *px, int *py)  

  2. {  

  3.   int tmp=*px;  

  4.   *px=*py;  

  5.   *py=tmp;  

  6.   print(“*px=%d, *py=%d\n”, *px, *py);  

  7. }  

  8.   

  9. void main()  

  10. {  

  11.   int a=2;  

  12.   int b=7;  

  13.   swap2(&a,&b);  

  14.   Print(“a=%d, b=%d\n”, a, b);  

  15. }  

这次输出结果是什么?

*px=7, *py=2

a=7, b=2


3. 

[plain]  view plain  copy




  1. void swap3(int &x, int &y)  

  2. {  

  3.   int tmp=x;  

  4.   x=y;  

  5.   y=tmp;  

  6.   print(“x=%d, y=%d\n”, x, y);  

  7. }  

  8.   

  9. void main()  

  10. {  

  11.   int a=2;  

  12.   int b=7;  

  13.   swap3(a,b);  

  14.   Print(“a=%d, b=%d\n”, a, b);  

  15. }  

那这次输出结果又是什么?


x=7, y=2

a=7, b=2


接下来,分析一下为什么是这样的结果呢?

上面的1,2,3分别是值传递,地址传递,和引用传递。

先看值传递。swap1函数的操作是将x,y进行对调。需要注意的是,对形参的操作不会影响到a,b。我们可以设想,在swap1函数执行语句的最前面,隐含地存在x=a; y=b;这两条语句,这样就便于理解了。当a,b把值赋给x,y之后,对x,y不论再做什么操作,都不会影响到a,b本身。


再看地址传递。注意,这时的函数的声明和调用的写法与值传递不同。

函数声明:swap2(int *px, int *py)

函数调用:swap2(&a, &b)

但是与值传递的分析一样,我们同样可以设想,在swap2函数里,隐含地存在px=&a; py=&b;这两条语句,这表示a的地址代入到了px,b的地址代入到了py。这样一来,对*px, *py的操作就是a,b本身的操作。所以a,b的值被对调了。


接下来看引用传递。先看函数的声明和调用的写法,函数调用和值传递的写法是一样的,但是函数声明是不一样的。

函数声明:swap3(int &x, int &y)

函数调用:swap3(a, b)

因为定义的x,y前面有&取地址符,调用函数swap3时,a,b分别代替了x,y,即x,y分别引用了a,b变量。因此,函数里的操作,实际上是对实参a,b本身的操作,其值发生了对调。


猜你喜欢

转载自blog.csdn.net/weixin_42255385/article/details/82048683
今日推荐