C传递参数参考

时间:2011-10-20 15:32:40

标签: 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);
}

C实际上是否允许这样做,即使实际修改do_one_thing以写入pInput,事情可能会爆发吗?

6 个答案:

答案 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);
}

答案 1 :(得分:1)

是C会允许此操作,do_many_thing会将SomeStruct_t的副本作为input传递,然后您将地址传递给do_one_thing,该地址可以自由读取或写入到结构。 do_many_thing的调用者不会看到对传递的结构执行任何更改。

答案 2 :(得分:0)

这是完全合法的代码。如果do_one_thing写入pInput的数据,它也不会爆炸。如果程序员意识到在do_many_thing结束时do_one_thing所做的更改已经消失,那么这也是完全有效的。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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

然后当你调用这个函数时,你会这样做:

do_one_thing(input);

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

答案 5 :(得分:0)

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

do_many_thing收到一些结构的副本input。然后,您可以通过将此副本传递到do_one_thing来修改此副本。除非你依赖该副本没有改变,否则一切都不会发生。此外,do_many_thing的来电者不会看到传入SomeStruct_t的更改,因此即使在较高级别也不会有副作用。