怎么了:
因为您按值传递指针,所以在函数中创建了一个本地副本f
,然后您将另一个值(指向 b 的指针)分配给该副本并离开该函数。原始指针保持不变。
现在让我们假设,您通过以下方式修改函数:
void f(int * & p){
int b = 10;
p = &b;
}
不要在家里这样做!
现在,实际的指针被传递给函数,没有创建副本。然后将指向 b 的指针分配给它并返回函数。然后你尝试访问 - 一个值所指向p1
的值,该值不再有效,因为b
不再存在。你在这里得到一个未定义的行为:最好的情况是一切实际上都会像你想象的那样工作,最坏的情况是你会遇到访问冲突或更糟 - 你的程序的一些数据可能会被破坏(一切取决于在平台和编译器上)。
为什么 C++ 编译器不通知你呢?通常是因为 C++ 不应该照顾你,这样你就不会踢自己的脚(实际上,使用 C++ 有很多方法可以踢自己的脚,如果你堆叠包含这些的书籍,你会到达月球)。C++ 只是做你告诉它的事情。你想得到指针b
吗?好的,没问题。你想从函数返回一个指针吗?为什么不呢,那只是一个 32 位整数值。
关键是,在用 C++ 编写时,你必须非常小心,不要编写这样的代码。
编辑:回应评论
想象一下,该数据是一座建筑物,而指针是一张带有该建筑物地址的纸。当您按值传递指针时:
void f(int * p)
就像您拿了另一张纸并复制了地址。如果您随后将其擦除并更改为另一张,则原始纸张上的原始地址将保持不变。
现在,如果您执行以下操作:
void f(int * p)
{
*p = 4;
}
就像你真的去了纸上写的地址,改变了大楼里的东西。如果你然后去原始纸上存储的地址,建筑物将被改变。
最后,如果您执行以下操作:
void f(int * & p)
{
}
就像您将原始纸张传递给函数一样,因此如果您更改地址,它也会在函数之外更改。
希望这可以帮助您了解指针的工作原理。