一个例子让你理解c++的指针(传递动态内存)

经常搞不懂C/C++的指针,但是指针是C系语言的特点,也是它的精华所在,指针即一个数据对象的内存地址。指针问题,包括常量指针、数组指针、函数指针、this指针、指针传值、指向指针的指针等都是各大公司的常备考点。下面我们就来看看一个例子,好好理解理解指针吧

#include <iostream>
using namespace std;

void swap1(int p,int q){

    int temp;
    temp = p;
    p = q ;
    q = temp;
}

void swap2(int *p,int*q){
   int *temp;
   *temp = *p;
   *p = * q;
   *q = *temp;
}

void swap3(int *p,int *q){
  int *temp;
  temp = p ;
  p = q;
  q = temp;
}
void swap4(int *p,int *q){
  int temp;
  temp = *p;
  *p = *q;
  *q = temp;

}
void swap5(int &p,int &q){
 int temp;
 temp = p;
 p = q;
 q = temp;

}
int main(){
 int a,b;
 swap1(a,b);
 //swap2(&a,&b);
 //swap3(&a,&b);
 //swap4(&a,&b);
 //swap5(a,b);
cout<<a<<" "<<"b"<<endl;
return 0;
}

这个例子包含了函数参数传递、值传递、指针传递(地址传递)、引用传递的知识点

分别执行swap1(a,b)、swap2(a,b)、swap3(a,b)、swap4(a,b)、swap5(a,b);

他们会有何不同的结果


1.对于sawp1(a,b)来说,p和q就是形参,a,b是实参,swap1传的是值得副本,只是在函数体内修改了形参p,q的值,p和q的值确实是交换了,但是他们只是局部变量,并不会影响到主函数的a和b;当函数生命周期结束时,p和q所在的栈也就被删除了


2.swap2(&a,&b)传的是一个地址进去,在函数体内的形参*p和*q是指向了实际参数a,b的内存地址的指针

but!!!

要注意!


int *temp;
*temp = *p;

这段代码的意思是:我新建了一个指针*temp;但是并没有给他分配内存,所以

*temp = *p是赋值而并非指向!要注意理解,就是将指针p所指向的内存里的值赋值到指针temp所指向的内存里的值。但是不是没有给*temp分配内存吗?所以,系统就在赋值的时候临时的给*temp随机的地址,让它存值。分配的随机地址是个“意外”,并且函数结束后还不收回!!这样就会造成内存泄漏!!如下图


那么到底这段代码能否实现数据交换?其实还得看编译器,像vs2008这样严格一点的编译器,是会报错的

3.swap3(a,b)传的是一个地址过去,与swap2不同的是

*temp = *  p ;//swap2 赋值
temp = p; //swap3 指向
/*swap2和swap3同样都没给temp指针分配内存
 *不同的是以上这两段代码。temp=p是指向,而不是复制了,temp是指向了p指针所指向的地址,也就是a
 */

而代码
p = q;
q = temp;
/*其意思就是指针p指向了指针q所指向的地址,q又指向了指针temp所指向的地址,其实和temp=p是一个意思;
如下图所示
*/


所以swap3只是改变了指针的指向,并没有改变a,b的值。

举一个很形象的例子。假设有a,b两个仓库,p和q分别是它们的备用钥匙(注意是备用!),现在我们进入了函数体swap3(), 使得p,q钥匙的功能改变了,p用来打开b仓库,q用来打开a仓库,但是a仓库本身的货物并没有发生什么变化,里面存放的是大米现在也依然是大米,b仓库原来放的是辣椒那现在也还是辣椒。函数结束,两把备用的“钥匙”就会自动销毁,而主函数里用主钥匙打开a,b仓库,发现值还是没变化。

4.swap4,修改了指针所指向的地址中的值

int *temp;
temp = *p;
*p = q;
*q = temp;
将指针p所指向的地址的值赋值给temp指针所指向的地址,*p=q,就是q指针所指向的地址赋值给指针p所指向的地址中的值,所以指针p所指向的a(地址)中的值就变成了b(b是q指针所指向的地址),同理指针temp所指向的地址就赋值给了q指针所指向的地址中的值,也就是说将最初p指针所指向的地址的值赋值给了q指针所指向的地址的值。没毛病,其实交换的本质就是这样的:最初的p的值要换成q的值,而q的值要换成最初p的值,所以只是将最初p的值给临时保存下来。

5.swap5和swap4是类似的。是一个引用传递,修改的结果直接影响实参。

void swap5(int &p,int &q){
int temp = p;
p = q;
q = temp;
}
所谓的引用传递就是指在调用函数的时候,将实参的地址传递到函数中,那么在函数中对参数所进行的修改,将会影响到实际的参数.将一个变量引用传递给函数,这样该函数就可以修改其参数(变量)的值。因为实参和形参 引用了同一个地址,所以如果改变了形参的值,那么实参的值也将会发生变化。

 
  
 

猜你喜欢

转载自blog.csdn.net/sinat_35803474/article/details/76686061