背景:
最近刚开始自学数据结构,大学学的实在是云里雾里的,想着自己用C++实现一下伪代码吧,大概思路是这样的:
在main里定义了一个SqList *L = NULL;
在InitList(SqList *L);函数里new出来一块内存分配给L:
L = new SqList();
因为L是在main里定义的,按照我所预想的,在初始化函数里分配了内存块就OK了,因为指针传参传递的是地址,所以L肯定被改变了。
但是事实是,一旦退出了InitList之后,L的地址就回归到了坑爹的全0
我通过指针传递参数,并试图在函数体内改变指针,但是发现这只是改变了函数体内的指针,函数结束后,main里的指针还是任尔东南西北风我自岿然不动
一、 你所传递和改变的到底是什么
为什么会这样呢?明明我以前做指针传参的话,值都改变了啊(你大概会这么想)
废话不多说,百思不得其解的时候可以通过一个小demo测试一下
#include <iostream> using namespace std; void changePointer(int *p) { p = new int(1); cout << "p in = " << p << endl; } int _tmain(int argc, _TCHAR* argv[]) { int *p =new int(0); cout << "p1 = " << p << endl; changePointer(p); cout << "p2 = " << p << endl; return 0; }
这个结果很坑爹的验证了之前的问题:
看到没有?
p在经过changePointer之后并没有改变其地址,问题就在这里:
我们平常是用指针传递参数,然后在函数体里改变指针保存的地址所存储的值,而不是改变指针所保存的地址,这里很多人都会偷换了概念
好吧,有一点绕口,上代码,仔细考虑一下以下两行代码的区别:
*p = 1; // p并没有被改变,但是p所指向的值被改变了 p = new int(1); // p被改变了
是不是不一样?好了,知道了为什么这个跟平时自己用的指针传参不一样之后,让我们考虑一下,是什么导致了p在函数体内被改变了,出了函数体就变回来了呢?
二、指针参数究竟是如何传递的
记得之前看过一个关于参数传递的文章,具体的不记得,大概有临时变量这么一说,既然是临时的,会不会出函数就over了,所以就导致了main中的p未被改变?
记忆总是模糊的,我们可以问度娘
事实证明确实是这样的
问过度娘之后,得到这么一句话:
编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。
而如果我们修改的是_p保存的地址,而非_p地址指向的值,那么函数结束之后,临时变量被修改和p有毛关系呢
三、怎么样才能达到我们的预期目的——改变指针
1. 比较简单的一种是:返回值
直接把在函数体里new出来的返回就好了嘛~~~
检验一下:
int* changePointer(int *p) { p = new int(1); cout << "p in = " << p << endl; return p; } int _tmain(int argc, _TCHAR* argv[]) { int *p =new int(0); cout << "p1 = " << p << endl; p = changePointer(p); cout << "p2 = " << p << endl; return 0; }
输出:
Good job~!你妹的指针终于被改了有木有~~~
2. 指针的指针
void changePointer(int **p) { *p = new int(1); cout << "p in = " << *p << endl; } int _tmain(int argc, _TCHAR* argv[]) { int *p =new int(0); cout << "p1 = " << p << endl; changePointer(&p); // 注意这里传递的是&p cout << "p2 = " << p << endl; return 0; }
输出:
作为一个渣渣,C++慢慢抠语法抠底层真的很辛苦,成为大神之路任重而道远
干吧呆,小伙伴们