暑假到了,想复习一下本科学过的C++,顺便刷刷力扣,突然发现写了一年python被语法糖包围之后完全忘记了最神圣的语言是如何管理内存的。
先来看一段教科书里最经典的案例
int exchange(int a, int b)
{
int p = a;
a = b;
b = p;
return 0;
}
int main()
{
int a = 1;
int b = 2;
exchange(a, b);
}
这段代码不会起任何作用,因为参数传递是值的copy,函数内部是新建了变量去执行操作的,当e函数结束的时候变量被释放。和原先的a,b没有任何关系。
int exchange(int &a, int &b)
{
int p = a;
a = b;
b = p;
return 0;
}
int main()
{
int a = 1;
int b = 2;
exchange(a, b);
}
这样是能成功完成交换的。因为函数接受的是对象的引用。这里有一个地方我记得以前一直会搞混,容易把函数参数列表中的 int &a 理解成是a的地址,也就是说我以前的理解是这里接受的是a的地址。但是我们在main函数中调用时传入的是int 类型的数,这两者显然是不匹配的。所以我在excange内部打印:
int exchange(int &a, int &b)
{
int p = a;
a = b;
b = p;
return 0;
}
int main()
{
int a = 1;
int b = 2;
exchange(a, b);
cout << &a << endl<<&b<<endl;
exchange(a, b);
cout << &a << endl << &b << endl;
cout << a << b;
}
得到的结果是
两个变量存放的地址并没有发生改变,改变的只是值。
再来看一个例子。
int exchange(int *x, int *y)
{
int p = *x;
*x = *y;
*y = p;
return 0;
}
int main()
{
int a = 1;
int* aa = &a;
int b = 2;
int* bb = &b;
cout << &aa << endl << &bb << endl;
exchange(aa, bb);
cout << &aa << endl << &bb << endl;
cout << a << b << endl;
}
注意到aa bb的地址都没有发生变化(把&符号去掉他们的值也就是他们所指向的地址也没有发生变化)。因为等号只会改变等号左边的值,函数内部改变的是指针解引用之后的整形。
与之前通过引用的方式修改进行对比:
这里就可以理解为:指针和引用本质上都是对于对象的间接访问,只是在具体的实现上二者有很大的不同。