【问题标题】:How to affect the same copy of a struct in C?如何影响C中结构的相同副本?
【发布时间】:2017-03-21 03:04:11
【问题描述】:

我是 C 的新手,所以请多多包涵 :) 我正在尝试学习这门语言,但在尝试更改同一结构的元素时遇到了麻烦。

考虑以下代码:

#include <stdio.h>

struct aStruct{
  int someNum;
};//end wordGuessResources struct

int updateSomeNumber(struct aStruct thing){
  printf("\nBefore updating someNum is %d.", thing.someNum);
  thing.someNum++;
  printf("\nAfter updating someNum is %d.", thing.someNum);
  return 0;
}

int main(){
  struct aStruct thing;
  thing.someNum = 2;
  updateSomeNumber(thing);
  printf("\nIn main, someNum is now %d.", thing.someNum);
  updateSomeNumber(thing);
  printf("\nIn main, someNum is now %d.", thing.someNum);

  return 0;
}//end main

运行此代码将产生输出:

Before updating someNum is 2.
After updating someNum is 3.
In main, someNum is now 2.
Before updating someNum is 2.
After updating someNum is 3.
In main, someNum is now 2.

很明显,当我第一次将thing 传递给updateSomeNumber 时,它正在接受thing 的相同副本,因为它已经知道someNum 是2(见输出的第一行)。

但似乎正在发生的是,在它影响thing 的值之后,当我们返回main 函数时,似乎没有记录任何更改(因为在mainsomeNum仍然是 2,而不是 3)。

所以我推测updateSomeNumber 一定是在获取最初在 main 中编辑的thing 的副本,但没有修改原始实例?

如果确实如此,我如何将main 使用的thing 的确切实例传递给函数,以便影响该实例?

【问题讨论】:

  • 结构是传值的; main() 中的结构副本被传递给函数。函数修改副本;它不会也不会影响main() 中的原件。您需要将指向结构的指针传递给函数,以便修改原始结构。有相应的符号变化(.-&gt; 等)。
  • main,做updateSomeNumber(&amp;thing);。然后,将 fnc 的定义更改为:int updateSomeNumber(struct aStruct *thing)。然后,在 fnc 中,thing. --> thing-&gt; 当传递 struct 时,几乎所有代码都围绕指针传递。由于您遇到的原因,因此几乎从未使用过按值传递。如果您的结构有 50 个不同的项,并且通过值传递,则它们都必须被压入堆栈,从而使代码变慢。
  • @CraigEstey 好的,完美!这就说得通了。我现在看到了,所以我将结构的地址传递给函数,然后在编辑它们时只使用引用函数中值的指针。我现在明白了,谢谢!
  • 我确实为我在问题中所做的任何错误而导致投票失败表示歉意。有人可以向我解释我做错了什么,以便我修复它吗?

标签: c function struct


【解决方案1】:

您需要使用Pointers。基本上,您需要将 thing 结构的地址而不是 thing 本身传递给您的更新函数。然后您的更新函数需要更新作为函数参数接收的地址处的thing。请参阅以下示例:

#include <stdio.h>

struct aStruct{
  int someNum;
};//end wordGuessResources struct

int updateSomeNumber(struct aStruct * thing){
  printf("\nBefore updating someNum is %d.", thing->someNum);
  thing->someNum++;
  printf("\nAfter updating someNum is %d.", thing->someNum);
  return 0;
}

void main(){
  struct aStruct thing;
  thing.someNum = 2;
  updateSomeNumber(&thing);
  printf("\nIn main, someNum is now %d.", thing.someNum);
  updateSomeNumber(&thing);
  printf("\nIn main, someNum is now %d.", thing.someNum);
}//end main

这是输出:

Before updating someNum is 2.                                                                                                                                                   
After updating someNum is 3.                                                                                                                                                    
In main, someNum is now 3.                                                                                                                                                      
Before updating someNum is 3.                                                                                                                                                   
After updating someNum is 4.                                                                                                                                                    
In main, someNum is now 4.

【讨论】:

  • 事物本身这些词具有误导性,因为传递了主要事物的副本
  • 谢谢,这是有道理的。这些信息与@CraigEstey 在他的评论中给出的信息相同,因为他首先发表了评论,所以我会给他机会将其发布为答案。但如果他不发布,我会接受你的。谢谢你们两个:)
  • @Guy,在发布我的答案之前,我没有阅读他或任何人的评论。像上面那样发布一个完整的答案比发表评论需要时间。但选择权在你。
  • 无论如何我都赞成这个答案,因为它回答了这个问题。不过,克雷格似乎不会给出答案,所以我会接受这个。
  • @RolandIllig 说 f(5) 将 5 传递给 f 是否具有误导性?我应该说它通过了 5 的副本吗?
猜你喜欢
  • 1970-01-01
  • 2014-02-26
  • 1970-01-01
  • 2020-02-21
  • 2021-08-31
  • 2014-08-22
  • 2020-01-19
  • 1970-01-01
  • 2014-09-06
相关资源
最近更新 更多