C 参考传递混淆

C 参考传递混淆,c,memory-management,memory-leaks,pass-by-reference,C,Memory Management,Memory Leaks,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(si

考虑以下示例,其中我尝试以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;
}
//函数原型
无效增量(无符号*数字);
int main()
{
无符号*事物;
增量(事物);

coutC没有pass-by引用。除数组外,所有参数都是按值传递的

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

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


这基本上是在C++中使用引用时发生的事情。在C中,必须显式地编码额外的间接级别。

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

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


这基本上是在C++中使用引用时发生的事情。在C中,你必须明确地对额外的间接级别进行编码。

< P>第二种方式是正确的方式。第一种方法不起作用的原因是,当代码> >编号>代码>实际上,你正在修改<代码>号码<代码>。因此,尽管您实际上通过引用将变量
thing
传递给
increment
,但
thing
的地址已通过值传递给
increment

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

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

void increment(unsigned* number);

int main()
{
    unsigned thing;
    increment(&thing);
    cout << thing;
    return 0;
}

void increment(unsigned* number)
{
    *number = 1;
}
无效增量(无符号*数字);
int main()
{
未签名的事物;
增量(和事物);

cout也许你要找的是这样的东西:

void increment(unsigned* number);

int main()
{
    unsigned thing;
    increment(&thing);
    cout << thing;
    return 0;
}

void increment(unsigned* number)
{
    *number = 1;
}
无效增量(无符号*数字);
int main()
{
未签名的事物;
增量(和事物);

cout在示例的上下文中说通过引用传递意味着传递指向对象的指针

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

int main()
{
    unsigned* thing;
    //...
因此,要通过引用传递类型为
unsigned*
的对象
thing
,必须传递指向该对象的指针

void increment(unsigned** number);

int main()
{
    unsigned* thing;
    increment(&thing);
    //...
我认为如果引入typedef,您会更清楚

typedef unsigned* T;

void increment( T* number);

int main()
{
    T thing;
    increment( &thing );
    //...

我希望现在更清楚了。:

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

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

int main()
{
    unsigned* thing;
    //...
因此,要通过引用传递类型为
unsigned*
的对象
thing
,必须传递指向该对象的指针

void increment(unsigned** number);

int main()
{
    unsigned* thing;
    increment(&thing);
    //...
我认为如果引入typedef,您会更清楚

typedef unsigned* T;

void increment( T* number);

int main()
{
    T thing;
    increment( &thing );
    //...

我希望现在更清楚了。

黄金法则:参数总是按值传递。您只更新了指针的本地副本。它没有传播回调用方,因为它是按值kaboom传递的。请注意,在工作版本中,您没有更改number参数。您更改了*number,就像您应该做的那样。我正在使用C++与嵌入式C对话的应用程序,我认为这就是为什么它令人困惑的原因。C不支持按引用传递。VS-compiler使用CGolden规则接受按引用传递:参数总是按值传递。您只更新了指针的本地副本。它没有传播回调用方,因为它是按值kaboom传递的。注意在工作版本中,你没有改变数字参数。你改变了数字,就像你应该。我正在研究一个C++应用程序,它与嵌入式C对话,我想这就是为什么它会混淆。C不支持通过引用。VS编译器接受CAHHW的通过引用,谢谢!我正在C++程序之上工作C++程序,所以我花了一些时间才弄明白这一点。感谢您的简单解释。“除了数组,所有参数都是按值传递的。”所有参数都是按值计算的。不可能有数组类型的参数。@newacct您不能有数组类型的参数,但可以使用数组作为参数,并且不能复制。由于它被转换为指针,所以它的作用很像按引用传递,因为对函数中数组的更改会影响调用者的变量。啊哈哇,谢谢!我正在C++程序上做一个C++程序,所以我花了一段时间来理解它。欣赏你的简单解释。“除了数组,所有的参数都是按值传递的。”所有的参数都是按值排列的。不可能有数组类型的参数。@ NeXACT,你不能有一个参数。