将值传递给 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;
至于第一个函数定义,那么函数参数就是它的局部变量。参数由参数值的副本初始化。所以在函数内,它是被改变的副本。原论点不变。如果要在函数中使用指向参数的指针更改参数,则需要通过引用传递参数。
这是我当前代码的布局,
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;
至于第一个函数定义,那么函数参数就是它的局部变量。参数由参数值的副本初始化。所以在函数内,它是被改变的副本。原论点不变。如果要在函数中使用指向参数的指针更改参数,则需要通过引用传递参数。