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

来源:互联网 发布:软件著作权技术特点 编辑:程序博客网 时间:2024/06/05 20:07

经常搞不懂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;}
所谓的引用传递就是指在调用函数的时候,将实参的地址传递到函数中,那么在函数中对参数所进行的修改,将会影响到实际的参数.将一个变量引用传递给函数,这样该函数就可以修改其参数(变量)的值。因为实参和形参引用了同一个地址,所以如果改变了形参的值,那么实参的值也将会发生变化。

原创粉丝点击