2012-05-04 63 views
8

請多多包涵,我從其他語言和新手m設置爲c和從http://c.learncodethehardway.org/book/learn-c-the-hard-way.html定義一個函數返回結構指針

struct Person { 
    char *name; 
    int age; 
    int height; 
    int weight; 
}; 

struct Person *Person_create(char *name, int age, int height, int weight) 
{ 
    struct Person *who = malloc(sizeof(struct Person)); 
    assert(who != NULL); 

    who->name = strdup(name); 
    who->age = age; 
    who->height = height; 
    who->weight = weight; 

    return who; 
} 

學習它,我明白了第二Person_create函數返回結構Person的指針。我不明白的是(可能是因爲其他語言,二郎,紅寶石IM),爲什麼它把它定義爲

struct Person *Person_create(char *name, int age, int height, int weight) 

,是有其他的方式來定義一個函數返回結構?

對不起,如果這個問題太基本了。

+0

瞭解'Person *'和'Person'之間的區別。 'Person *'是一個指向對象的指針,而'Person'是對象本身。兩者都是不同的類型,例如'int *'和'int'的不同。 – Mahesh

+1

因此,'struct Person * Person_create'與'struct Person * Person_create'和'struct Person * Person_create'是一樣的嗎? '*'的位置並不重要? – allenhwkim

+1

是的,'*'周圍的空白在這裏並不重要。 –

回答

11

它是這樣定義的,因爲它返回一個指向結構的指針,而不是結構。您將返回值分配給struct Person *,而不是struct Person

它可以返回一個完整的結構,這樣的:

struct Person Person_create(char *name, int age, int height, int weight) 
{ 
    struct Person who; 
    who.name = strdup(name); 
    who.age = age; 
    who.height = height; 
    who.weight = weight; 
    return who; 
} 

但它並不常用。

3

函數返回who,這是一個struct Person * - 指向結構的指針。保存結構的內存由malloc()分配,並且函數返回指向該內存的指針。

如果函數聲明返回struct Person而不是指針,那麼who也可以聲明爲結構。返回後,該結構將被複制並返回給調用者。請注意,該副本不如將指針返回到內存的效率低。

2

在C/C++中,缺省結構不是指針(或引用),就像它們在Java中一樣。 Struct Person Function()將爲此返回結構本身(通過值,複製)而不是指針。

您通常不希望創建對象的副本(默認情況下爲淺度副本,或者使用副本構造函數創建的副本),因爲這可能會很快消耗相當多的時間。

1

複製整個結構而不僅僅是指針效率不高,因爲指針的sizeof通常比整個結構本身的sizeof小得多。另外,一個結構可能包含指向內存中其他數據的指針,並且盲目複製可能會對動態分配的數據造成危險(如果處理一個副本的代碼釋放它,另一個副本將留下無效指針)。

如此淺的副本幾乎總是一個壞主意,除非您確定原始程序超出了範圍 - 然後您爲什麼不直接返回指向該結構的指針(一個結構動態分配在堆當然,所以它不會像堆棧分配的實體被銷燬一樣從函數返回時被銷燬)。

2

Person_create函數返回指向struct Person的指針,因此您必須將返回值定義爲指針(通過添加*)。要理解返回指向結構體的指針而不是結構本身的原因,必須理解C處理內存的方式。

當您在C中調用函數時,您在call stack上爲其添加記錄。調用堆棧的底部是正在運行的程序的main函數,頂部是當前正在執行的函數。堆棧中的記錄包含諸如傳遞給函數的參數值和函數的所有局部變量之類的信息。

程序有權訪問另一種類型的內存:堆內存。這是您使用malloc分配空間的位置,它未連接到調用堆棧。

當你從一個函數返回時,調用棧會彈出,並且所有與函數調用相關的信息都將丟失。如果你想返回一個結構體,你有兩個選擇:在結構體內部從數據調用堆棧中彈出之前複製數據,或者將數據保存在堆內存中並返回一個指向它的指針。複製字節的數據字節比單純返回指針要昂貴得多,因此通常希望這樣做可以節省資源(內存和CPU週期)。但是,它並非沒有成本;當你將數據保存在堆內存中時,你必須記住它到free當你停止使用它時,否則你的程序會泄漏內存。

相關問題