关于c语言中的传值和传址的探究

本文通过C++代码示例对比了传值与传址的区别,详细解释了为何必须使用传址来实现参数的交换。并通过不同场景展示了如何正确使用指针以达到预期效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记得大学老师讲数据交换的时候告诉我们要想达到交换的效果必须要使用传址的方式,为什么是这样?

先看代码:

#include<iostream>
using namespace std;
void sort(int a,int b){
  cout<<&a<<','<<&b<<endl;
  if(a>b){
    int m=a;
    a=b;
    b=m;
  }

}

int main(){
  int a=10,b=5;
  cout<<&a<<','<<&b<<endl;

  sort(a,b);
  cout<<a<<','<<b<<endl;
  cout<<&a<<','<<&b<<endl;
}
运行结果:

0xbfb1559c,0xbfb15598
0xbfb15580,0xbfb15584
10,5
0xbfb1559c,0xbfb15598

-----------

从结果可以看出,a,b没有完成交换,原因其实很简单,从运行结果来看,sort中的a,b的内存地址和main函数中a,b的内存地址不一样,

可以认为main函数的a,b值被复制了一份放在sort函数栈中,那么这2个内部栈的数据的交换对main函数的中的a,b没有任何影响,这就可以理解为什么a,b没交换了。

==========================================================================================

现修改代码如下:

#include<iostream>
using namespace std;
void sort(int *a,int *b){
  cout<<&a<<','<<&b<<endl;

  cout<<a<<','<<b<<endl;
  if(*a>*b){
    int m=*a;
    *a=*b;
    *b=m;
  }

}

int main(){
  int a=10,b=5;
  cout<<&a<<','<<&b<<endl;

  int *p1=&a;

  int *p2=&b;

  sort(p1,p2);

  cout<<&p1<<','<<&p2<<endl;
  cout<<a<<','<<b<<endl;
  cout<<&a<<','<<&b<<endl;
}
运行结果:

0xbfde1f6c,0xbfde1f68
0xbfde1f64,0xbfde1f60
0xbfde1f50,0xbfde1f54
0xbfde1f6c,0xbfde1f68
5,10
0xbfde1f6c,0xbfde1f68
结论如下:

1.a,b的值交换了。也是我们想要的效果。

2.a,b的地址没变。

3.传指针进去,也是将指针复制一份,从我们的输出可以看出,p1、p2的地址和sort中指针的地址是不一样,

我们可以理解为复制了一份指针。

分析如下:

   把a ,b的地址通过参数传给sort,虽然是复制了一份指针,但是这个指针的值是不变,也就是这2个不同的指针

  指向了同一块内存块,那么我们对这个内存块里面的数据修改是可以改变值的。

  但是a,b的内存地址是不会变的,在我们的变量被定义的时候指定地址,除非这块内存被释放,期间地址是不会变的。

===================

更好的理解传值和传址,修改sort函数如下:

 void sort(int *a,int *b){
  cout<<&a<<','<<&b<<endl;

  cout<<a<<','<<b<<endl;
  if(*a>*b){
    int* m=a;
     a=b;
     b=m;
  }

}

运行结果如下:

0xbfcc0b0c,0xbfcc0b08
0xbfcc0b04,0xbfcc0b00
0xbfcc0af0,0xbfcc0af4
0xbfcc0b0c,0xbfcc0b08
10,5
0xbfcc0b0c,0xbfcc0b08
我们看到a,b的值没有交换,这是为什么呢,用我们上面的理解:

复制的指针做了交换,但是外面的指针并没有变,所以值也不会变。.

综上述,所有的参数传递都是复制一份值保存在被调用的函数的函数栈中,如果要改变传进去的参数的值,必须要通过传递

这个参数的地址,并且要在被调用的函数中,对传递进来的地址里面的数据做修改,而不能对地址做修改。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值