对传递引用感到困惑

考虑以下示例,我尝试以C方式传递引用:

// Function prototypes void increment(unsigned* number); int main() { unsigned* thing; increment(thing); cout << *thing; return 0; } void increment(unsigned* number) { number = (unsigned*) malloc(sizeof(unsigned)); *number = 1; } 

我在行cout << *thing遇到程序崩溃。 是的,我在这里使用C ++但是我想尝试C版本的pass-by-reference,因为我的主要项目是在C.

我通过更改代码修复它,如下所示:

 // Function prototypes void increment(unsigned** number); int main() { unsigned* thing; increment(&thing); cout << *thing; return 0; } void increment(unsigned** number) { *number = (unsigned*) malloc(sizeof(unsigned)); **number = 1; } 

现在它工作,输出为1,就像我预期的那样。 但是,我不明白为什么。 我有点困惑为什么在顶部分层额外的指针解决了我的问题。

谢谢!

C没有传递引用。 除数组外,所有参数都按值传递。

在您的第一个版本中,您将按值传递变量。 在increment函数中,它分配内存并将其分配给局部变量number 。 但这对调用者的变量没有影响,因为只传递了它的值,而不是对变量的引用。 因此,当increment返回时, thing仍然未初始化,并且通过它的间接导致未定义的行为。

如果函数需要修改调用者的变量,则调用者必须传递指向变量的指针,而不仅仅是值。 这就是你在第二个版本中所做的。 然后函数可以通过指针间接更新变量。

当你在C ++中使用引用时,这基本上就是在幕后发生的事情。 在C中,您必须明确地编写额外的间接级别。

也许你正在寻找的是这样的:

 void increment(unsigned* number); int main() { unsigned thing; increment(&thing); cout << thing; return 0; } void increment(unsigned* number) { *number = 1; } 

在C中,所有函数参数都按值传递。 因此,您无法更改函数中的值并希望反映在调用者中。 但是,如果传入的值是指针,则可以更改它指向的内容。 在此示例中, thing的地址传递给increment 。 然后在incrementnumber包含mainthing的地址。 那么你可以改变指向的number (即thing ),然后当你返回的thing被修改了。

这与你的第二个例子略有不同,因为没有动态内存分配,我认为这是你的目标。

在示例的上下文中通过引用传递意味着将指针传递给对象。

指针本身就是程序中的对象

 int main() { unsigned* thing; //... 

因此,要通过引用传递此对象类型unsigned* ,您必须传递指向此对象的指针

 void increment(unsigned** number); int main() { unsigned* thing; increment(&thing); //... 

我想如果引入一个typedef会更清楚。 想象一下下面的例子

 typedef unsigned* T; void increment( T* number); int main() { T thing; increment( &thing ); //... 

我希望现在更清楚了。:)

您发布的第二种方式是正确的方法。 第一种方法不起作用的原因是,当number实际上已经通过值传递时,您试图修改number 。 因此,尽管事实上你已经通过引用传递了变量的thing ,但是thing地址已经传递给值increment