这是我当前代码的布局,
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(未更改)。我试着像{@ 3}}上的@R Sahu一样对待它们,
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
答案 0 :(得分:4)
一元运算符的优先级低于后缀运算符。所以像这样的表达
*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;
对于第一个函数定义,函数参数是其局部变量。参数由参数值的副本初始化。因此,在函数中,它是被更改的副本。原始论点没有变化。如果要在函数中使用指针更改它们,则需要通过引用传递参数。
答案 1 :(得分:2)
*DEF.foo
解析为*(DEF.foo)
,而不是(*DEF).foo
。这就是DEF->foo
形式存在的原因;只使用a->b->c->d
和*
的{{1}}版本会很糟糕。
答案 2 :(得分:2)
how to change value of variable passed as argument?中的解决方案仅有效,因为字符串常量的特殊属性。它们在函数退出后保持存在,详见"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?