将值传递给 C 上的 typedef 结构

Pass value to typedef struct on C

这是我当前代码的布局,

test.h

typedef struct{
        int aa;
        int bb;
        int cc;
} ABC;
extern ABC XYZ;  

void passValue(ABC DEF,int a, int b, int c);
void doSomething();

test.c

ABC XYZ;

void passValue(ABC DEF,int a, int b, int c){
  DEF.aa = a;
  DEF.bb = b;
  DEF.cc = c;
}

void doSomething(){
  ...
  ...
  passValue(XYZ,10,20,30);
}  

但是当我在主程序上调用doSomething()时,该值仍然是0(没有改变)。我试着像对待@R Sahu 在 this question,

上的回答一样对待他们

test.h

typedef struct{
        int aa;
        int bb;
        int cc;
} ABC;
extern ABC XYZ;  

void passValue(ABC * DEF,int a, int b, int c);
void doSomething();

test.c

ABC XYZ;

void passValue(ABC * DEF,int a, int b, int c){
  *DEF.aa = a;  //error
  *DEF.bb = b;  //error
  *DEF.cc = c;  //error
}

void doSomething(){
  ...
  ...
  passValue(&XYZ,10,20,30);
}


ERROR : expression must have struct or union type

*DEF.foo 解析为 *(DEF.foo),而不是 (*DEF).foo。这就是 DEF->foo 形式存在的原因;仅使用 *.a->b->c->d 版本将是可怕的。

how to change value of variable passed as argument? is only valid, because of a special property of string constants. They keep existing after a function exits, as detailed in "life-time" of string literal in C

中的解决方案

每次将参数传递给函数时,都会创建该参数的副本。然后,您的所有更改都会应用到该副本,该副本会在您的函数结束后被丢弃。

您需要将要更改的对象的地址传递给您的函数,然后引用该地址以便将更改应用到结构的原始实例:

test.h

typedef struct{
        int aa;
        int bb;
        int cc;
} ABC;
extern ABC XYZ;



void passValue(ABC *DEF,int a, int b, int c);
void doSomething();

test.c

ABC XYZ;

void passValue(ABC *DEF,int a, int b, int c){
  DEF->aa = a;
  DEF->bb = b;
  DEF->cc = c;
}

void doSomething(){
  ...
  ...
  passValue(&XYZ,10,20,30);
}  

如果您想了解这一点,您应该阅读更多关于指针的内容: How do pointer to pointers work in C?

一元运算符的优先级低于后缀运算符。所以像这样的表达式

 *DEF.aa = a;  //error

相当于

*( DEF.aa ) = a;

所以你需要先应用一元运算符*,然后才应用后缀运算符

( *DEF ).aa = a;
( *DEF ).bb = b;
( *DEF ).cc = c;

或者您可以只使用后缀运算符 ->

DEF->aa = a;
DEF->bb = b;
DEF->cc = c;

至于第一个函数定义,那么函数参数就是它的局部变量。参数由参数值的副本初始化。所以在函数内,它是被改变的副本。原论点不变。如果要在函数中使用指向参数的指针更改参数,则需要通过引用传递参数。