2011-10-20 137 views
1

我遇到了一些遗留的C代码如下:C中传递参考参数

typedef struct _somestruct_ { 
/* .... */ 
} SomeStruct_t 

static void do_one_thing(SomeStruct_t *pInput){ 
    /* Do some read-only stuff with pInput */ 
} 


static void do_many_thing(SomeStruct_t input){ 
    do_one_thing(&input); 
} 

不ç居然允许这种,即使事情,如果do_one_thing可能会炸掉真正被修改写入pInput

+0

为什么你期望如果写入* pInput被炸掉? – NPE

+0

我没有看到这个问题。 –

回答

2

这是完全合法的C代码。代码do_one_thing(&input)只是将参数的地址传递给函数do_one_thing。这没有什么错。

如果do_one_thing写入pInput,这甚至不是问题。该地址是有效的并且指向可变值。进行更新没有任何问题。考虑

typedef struct _somestruct_ { 
int field; 
} SomeStruct_t 

static void do_one_thing(SomeStruct_t *pInput){ 
    // Completely legal 
    pInput->field = 42; 
} 

static void do_many_thing(SomeStruct_t input){ 
    do_one_thing(&input); 
} 
+0

谢谢。我想生病时必须继续寻找那些堆叠物来自哪里。 – nick

1

是c将允许这一点,do_many_thing将有SomeStruct_tinput通过副本,那么您通过地址do_one_thing这是免费的读取或写入结构。调用者do_many_thing将不会看到在传递的结构上执行的任何更改。

0

这是完全合法的代码。如果do_one_thing写入pInput的数据,它也不会炸毁。如果程序员知道do_one_thing的更改在do_many_thing结束时消失了,那么这也可以非常有效。

0

你基本上将一个指针传递给的值SomeStruct_t inputSomeStruct_t input是堆栈中的一个值,do_one_thing将修改堆栈值指针,但do_many_thing的调用者不会看到任何更改。

0

C没有通过引用传递,所以这种将指针传递给变量的方法是实现相同语义的唯一方法。

许多其他语言允许您直接通过引用传递。例如,在C++中,你可以做这样的:

static void do_one_thing(SomeStruct_t& Input){ 
    Input.foo++; 
} 

然后当你调用的函数,你做它像这样:

do_one_thing(input); 

但是,如果没有这种帮助,从语言你唯一的选择是指针。

0

您的代码清单可能并不完整,因此无法确切知道,但按照它看起来,它看起来不会“爆炸”。

do_many_thing收到一些结构的副本,如input。然后通过将其传递到do_one_thing来修改此副本。除非你在上依靠那个副本没有改变,否则什么都不会发生。而且,do_many_thing的调用者不会看到SomeStruct_t传入的更改,所以即使在更高级别也不会有副作用。