2016-02-21 56 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實現中,被調用的函數想要存儲指針,並且要將其存儲在由調用代碼定義的現有指針中。它需要知道在哪裏存儲指針,所以它需要一個指針指針。

相關問題