为什么在这种情况下我必须将指针传递给指针
Why do I have to pass a pointer to a pointer in this case
这个问题是建立在我 的基础上的。
我有这个结构。它使用 SDL2:
void init_window(SDL_Window *window)
{
window = SDL_CreateWindow(…);
}
int main(void)
{
SDL_Window *window;
init_window(window);
}
这没有用。答案建议,我改用 *&window
作为函数参数,效果很好。
我将 *&window
重写为 **window
如下:
void init_window(SDL_Window **window)
{
*window = SDL_CreateWindow(…);
}
int main(void)
{
SDL_Window *window;
init_window(&window);
}
而且它也有效。但是我仍然不明白为什么第一个版本不起作用。我查了 implementation details of SDL_Window and it's just a normal typedef
of a struct to put it into ordinary namespace. SDL_CreateWindow returns SDL_Surface *
.
为了描述我的困境,我写了这个简单的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Person
{
char *name;
int age;
} Person;
Person *person_create(char *name, int age)
{
Person *who = malloc(sizeof(Person));
who->name = strdup(name);
who->age = age;
return who;
}
void person_get_old(Person *who)
{
who->age += 30;
}
int main(void)
{
Person *susan = person_create("Susan", 23);
person_get_old(susan);
printf("%i\n", susan->age);
}
这会按预期打印 53
,而我不必使用指向指针语义的指针。 我的实现与 SDL2 的实现有何区别?这不是 SDL2 问题,因为回答我上一个问题的人可以在不了解 SDL2 的情况下回答这个问题,所以我似乎错过了一些实现细节。希望有人能赐教。
您的实现与 SDL2 的实现之间的区别在于,在您的实现中 returns 一个指针和调用代码将其分配给一个变量。
在SDL2实现中,被调用函数想要存储指针,而你希望它存储在调用代码定义的现有指针中。它需要知道在哪里存储指针,所以它需要一个指向指针的指针。
这里有一个更简单的例子来说明:
void foo(int p) //create new copy of int
{
p = 0; //modify copy, original is unchanged
}
void bar(int* p) //create new copy of pointer
{
*p = 0; //modify object pointer is set to
}
在您的 SDL 示例中,您试图执行 foo
。目标是将指针设置为新值。但是,您只复制了指针,所有更改都对副本进行了。
在您的 Person
示例中,您正在做 bar
。你有一个被指向的对象,你想修改它。正确的方法是通过指针(或引用)传递它。
既然你有一个你想要修改的对象,你需要通过指针(或引用)来传递它。由于该对象本身是一个指针,因此它将是一个指向指针的指针。
这个问题是建立在我
我有这个结构。它使用 SDL2:
void init_window(SDL_Window *window)
{
window = SDL_CreateWindow(…);
}
int main(void)
{
SDL_Window *window;
init_window(window);
}
这没有用。答案建议,我改用 *&window
作为函数参数,效果很好。
我将 *&window
重写为 **window
如下:
void init_window(SDL_Window **window)
{
*window = SDL_CreateWindow(…);
}
int main(void)
{
SDL_Window *window;
init_window(&window);
}
而且它也有效。但是我仍然不明白为什么第一个版本不起作用。我查了 implementation details of SDL_Window and it's just a normal typedef
of a struct to put it into ordinary namespace. SDL_CreateWindow returns SDL_Surface *
.
为了描述我的困境,我写了这个简单的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Person
{
char *name;
int age;
} Person;
Person *person_create(char *name, int age)
{
Person *who = malloc(sizeof(Person));
who->name = strdup(name);
who->age = age;
return who;
}
void person_get_old(Person *who)
{
who->age += 30;
}
int main(void)
{
Person *susan = person_create("Susan", 23);
person_get_old(susan);
printf("%i\n", susan->age);
}
这会按预期打印 53
,而我不必使用指向指针语义的指针。 我的实现与 SDL2 的实现有何区别?这不是 SDL2 问题,因为回答我上一个问题的人可以在不了解 SDL2 的情况下回答这个问题,所以我似乎错过了一些实现细节。希望有人能赐教。
您的实现与 SDL2 的实现之间的区别在于,在您的实现中 returns 一个指针和调用代码将其分配给一个变量。
在SDL2实现中,被调用函数想要存储指针,而你希望它存储在调用代码定义的现有指针中。它需要知道在哪里存储指针,所以它需要一个指向指针的指针。
这里有一个更简单的例子来说明:
void foo(int p) //create new copy of int
{
p = 0; //modify copy, original is unchanged
}
void bar(int* p) //create new copy of pointer
{
*p = 0; //modify object pointer is set to
}
在您的 SDL 示例中,您试图执行 foo
。目标是将指针设置为新值。但是,您只复制了指针,所有更改都对副本进行了。
在您的 Person
示例中,您正在做 bar
。你有一个被指向的对象,你想修改它。正确的方法是通过指针(或引用)传递它。
既然你有一个你想要修改的对象,你需要通过指针(或引用)来传递它。由于该对象本身是一个指针,因此它将是一个指向指针的指针。