我正在将我的一个项目从C ++转换为C,事情进展顺利,因为我没有使用很多C ++功能。但我遇到了一个特殊的问题,我已经设法在一个小的测试程序中复制了。这对我没有意义所以我会尝试用代码来解释。
typedef struct foo
{
int num1;
float num2;
char* name;
}foo;
//This function allocates and initializes a foo object
foo* Initfoo()
{
foo* f = malloc(sizeof(foo));
f->num1 = 1024;
f->num2 = 3.14;
f->name = malloc(100);
strcpy(f->name,"eleos re paidia");
//Just before returning here by checking the f pointer we can see
// it is initialized correctly
return f;
}
void afunctest(foo* f)
{
///... suppose this function does stuff before ...
//here it initializes the foo pointer
f = Initfoo();
///...and after here suppose the function also does more stuff..
//by checking at this point in the program the pointer is still initialized
//correctly to what InitFoo initialized it to
int asd =5;
}
int main()
{
foo* f = 0;
//should do stuff and also initialize the foo* f
afunctest(f);
//when we check here the pointer f is still 0 as if afunctest() function never ran
int asd = 5;
return 0;
}
所以基本上用几句话来说,我们声明一个foo指针并将其初始化为零。然后我们将该指针传递给afunctest()函数,该函数应该执行操作并初始化它以供以后使用。在afunctest()函数内部,它似乎是正确初始化的,但是一旦我们回到main(),它仍然具有值0,就像函数从未运行一样。
起初我认为这是我原始程序中一个非常错综复杂的错误,因为它已经变得非常复杂但是能够在这里复制它意味着我遗漏了与C ++相比在C中使用指针的基本原理。你们有人能说出来吗?我究竟做错了什么?提前感谢您的任何反馈。
P.S。:我的编译器是Windows 7下的GCC。
答案 0 :(得分:2)
您正在更改f
的本地副本。这对调用者没有任何影响。
void afunctest(foo* f)
{
f = Initfoo(); /* No effect for the caller of afunctest
}
尝试这样的事情:
void afunctest(foo **f)
{
/* ... */
*f = Initfoo();
}
/* In main. */
foo* f = 0;
functest(&f);
顺便提一下,还有C FAQ: Pass pointer Init。
答案 1 :(得分:1)
C通过值传递。如果要从f
内更改afunctest()
,则需要将指针传递给它并操纵它指向的值。
例如:
#include <stdio.h>
static void fn (int x, int *y) {
x = 42; // Changes local copy of x, doesn't affect a.
*y = 42; // Changes value *pointed to* by local y (which is b in caller).
}
int main (void) {
int a = 1;
int b = 1;
fn (a, &b); // Pass a and *address of* b.
printf ("%d %d\n", a, b);
return 0;
}
导致输出:
1 42
就您所拥有的代码而言,这将是:
void afunctest (foo **f) {
*f = Initfoo();
}
int main (void) {
foo* f = 0;
afunctest (&f);
return 0;
}
答案 2 :(得分:1)
解决方案实际上是直接安静 - 记住C总是按值传递所以当你在afunctest函数中设置f时,不会在主函数中更新你的f。
要做到这一点,你需要像这样使用** f:
void afunctest(foo** f)
{
//here it initializes the foo pointer
*f = Initfoo();
}
并称之为:
int main()
{
foo* f = 0;
//should do stuff and also initialize the foo* f
afunctest(&f);
return 0;
}