C++ 使用指针按引用和值传递

C++ 使用指针按引用和值传递,c++,pass-by-reference,parameter-passing,pass-by-value,C++,Pass By Reference,Parameter Passing,Pass By Value,我不明白为什么向函数传递指针不会改变传入的数据。如果函数proto如下所示: void func( int *p ); func为p分配了内存,为什么不能在函数之外使用呢?我还以为指针就是地址呢?很难说,你在问什么 我猜-您可以更改指针p指向的内存,但不能“重定向”或删除指针(或分配内存)?如果是这样,请将指针作为引用传递给您: void func(int&*p) 或作为双指针 void func(int**p) 为了能够更改它(我指的是指针)而这样的操作可以实现您的期望: void fun

我不明白为什么向函数传递指针不会改变传入的数据。如果函数proto如下所示:

void func( int *p ); 

func为p分配了内存,为什么不能在函数之外使用呢?我还以为指针就是地址呢?

很难说,你在问什么

我猜-您可以更改指针
p
指向的内存,但不能“重定向”或删除指针(或分配内存)?如果是这样,请将指针作为引用传递给您:
void func(int&*p)

或作为双指针
void func(int**p)


为了能够更改它(我指的是指针)

而这样的操作可以实现您的期望:

void func(int *p)
{
    *p = 1;
}

int a = 2;
func(&a);
// a is now 1
这是不可能的

void func(int *p)
{
    p = new int;
}

int *p = NULL;
func(p);
// p is still NULL
在这两种情况下,函数都使用原始指针的副本。不同之处在于,在第一个示例中,您试图操纵基础整数,因为您有它的地址,所以它可以工作。在第二个示例中,您直接操作指针,这些更改仅应用于副本


有各种各样的解决办法;这取决于你想做什么。< /P> < P> C和C++中的参数是通过值传递的。这意味着,如果参数的类型是指向
int
的指针,那么函数将接收实际指针参数的副本,同时仍然能够更改指向的
int

我不同意Nikolai的回答。在C++中,传递参数的方式有两种:< /P>
f(Type Name)
是您的情况,其中类型是
int*
,名称是
p
(注意
int*p
实际上是指
int*p
)。在这种情况下,函数名中是传递给函数的对象的副本

第二条路

f(Type & Name)
不进行复制,而是为对象创建一个别名,以便修改原始对象

在您的例子中,对象是
int*
类型的指针。当您使用第一种语法传递它时,您将得到一个修改过的副本,而原始指针保持不变。如果您想更改原始指针,那么应该通过引用传递它,因此对于Type=
int*
和Name=
p
您将得到

f(int*& p)

指针是地址。如果将指针传递给函数,则函数可以修改在函数范围外创建的数据。但是,如果要在函数内部分配内存以供函数外部使用,则需要传入双指针。原因是指针是按值传递的,分配会为新分配的块的指针分配一个新值。但当函数返回时,新值将丢失。但您可以使用此方法来完成所需的操作:

void func(int * * pp)
{
    * pp = new int;
}
因此,请使用func:

int * myPointer;
func(& myPointer);
// do stuff with myPointer
delete myPointer;

C++中的参数是通过值传递的…除非您通过引用传递;)@在这种情况下,引用是通过值传递的,对吗?@San:No,因为引用既不是对象也不是值。从技术上讲,你根本无法传递它们:C++中的引用非常特殊。引用的“价值”是不存在的,你不能引用引用等;我只是在装傻。然而,你可以整天争论语义。指针既不是对象也不是值。但是,指针可以指向一个对象,并包含一个表示该对象地址的值。同样,一个引用可以被认为包含一个值(可能实现为一个地址);它只是一个具有不同规则的值,因此您无法修改或读取地址。当您通过引用传递某个对象时,如果没有交换值,函数如何知道您“引用”的对象?因此最好制作一个这样的函数原型:func(int**p);或func(int*&p)?有什么真正重要的区别吗?@TheFuzz:这只是我个人的观点,其他人可能会强烈反对,所以要谨慎对待:我倾向于只在严格必要的地方使用引用,例如在操作符重载等。在其他位置,它们可能会导致混淆(因为仅仅通过查看函数调用,您无法判断它是按引用传递还是按值传递),并且它们比指针更受限制(不能为NULL,不能重新定位)。