2016-02-21 73 views
4

这个问题是建立在我的一个previous question为什么我必须在这种情况下传递指针指针

那里我有这个构造。它使用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,它只是一个普通的typedef结构把它放到普通的名字空间中。 SDL_CreateWindow返回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知识的情况下回答这个问题,所以似乎有一些我错过的实现细节。希望有人能够启发我。

+0

选择一种语言标签,C和C++是不同的。 (您的最后一个程序在C++中是无效的) –

+0

'auto init_window(SDL_Window ** window)'在C++中(在C++ 17之前!)和C中是非法的。您的编译器应对此进行评论。也许你打算返回'void';或者按照你在测试程序中使用的模型,并且使用'SDL_Window * init_window(void)' –

+0

我可以看到前两个在C中是无效的(C中不存在'auto'返回类型)以及第三个在C++('malloc')中是无效的,但我想知道为什么前两个在C++中也应该是无效的? – hgiesel

回答

3

这里有一个简单的例子来说明:

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。你有一个被指向的对象,并且你想修改它。正确的方法是通过指针(或引用)传递它。

由于您有要修改的对象,因此需要通过指针(或引用)传递它。由于该对象本身就是一个指针,它将是一个指向指针的指针。

3

你的实现和SDL2的实现之间的区别在于你的实现返回一个指针,调用代码将它分配给一个变量。

在SDL2实现中,被调用的函数想要存储指针,并且要将其存储在由调用代码定义的现有指针中。它需要知道在哪里存储指针,所以它需要一个指针指针。

相关问题