2014-04-01 61 views
3

我正在努力通過學習c的艱難的方式書,並遇到了練習19上的幾個問題。作者說,ex19是爲了讓學習者瞭解宏中的c 。我理解這個概念沒有問題,但我不明白其他的一切。我無法理解對象原型是如何創建的。一個簡單的對象系統

Especilly,以下說明是什麼意思?

由於C放Room.proto場第一,這意味着EL指針是 確實僅在足夠的存儲器塊以查看完整的 對象結構的指向。它不知道它甚至被稱爲原型。

相關的代碼是這樣的:

// this seems weird, but we can make a struct of one size, 
// then point a different pointer at it to "cast" it 
Object *el = calloc(1, size); 
*el = proto; 
  1. 誰能告訴我如何在地球上的malloc /釋放calloc準確的作品?據我所知,它只是分配所需數量的內存並返回第一個地址。如果是這樣,計算機如何知道分配內存的數據結構?喜歡在代碼中,Room *arena = NEW(Room, "The arena, with the minotaur");之後,你可以直接這樣做arena->bad_guy = NEW(Monster, "The evil minotaur");電腦怎麼知道有一個bad_guy
  2. 上述兩條語句(Object *el = calloc(1, size);*el = proto;)後面的* el的內容究竟是什麼?

任何幫助將不勝感激!

的鏈接練習:http://c.learncodethehardway.org/book/ex19.html

回答

0

它所做的是ALLOC 1*size字節。 malloc/calloc沒有什麼魔力。他通過NEW宏將sizeof(T)傳遞給函數,並將其放入Object_new的size參數中。所以所有的函數知道的是以字節爲單位的大小。

+0

內存「malloc」ed的類型由您分配返回值的指針類型所隱含。 malloc的大小通過「malloc」例程存儲(通常在返回地址之前的內存中),這就是「自由」神奇地知道當調用它時要返回多少內存。 – AnthonyLambert

4

calloc具有附加功能,它用零字節填充分配的內存,而使用等效的malloc調用將需要額外的步驟,如果全部或部分分配最初需要爲零。

在代碼

arena->bad_guy = NEW(Monster, "The evil minotaur"); 

編譯器知道該結構的佈局,因爲訪問是通過競技場變量,它被聲明爲一個指針間,這大概是一個結構的typedef

對於另一部分,在結構中進行排序的保證允許複合結構或擴展結構中的有限形式的繼承

struct A { 
    int x; 
}; 

struct B { 
    int foo; 
    double baloney; 
}; 

struct B(或一個指向它的指針)可以轉換爲一個(指針)struct A,因爲它們都與int開始。當然,如果您以其他方式進行投票,則struct A必須原先爲struct B,否則對baloney字段的訪問將不確定。換句話說,struct B基本上以struct A開頭。

如果我重寫我的例子是這樣,這可能是更容易地看到:

struct A { 
    int x; 
}; 

struct B { 
    struct A foo; 
    double baloney; 
}; 

現在你可以用不同的方式得到一個struct Astruct B

struct A a; 
struct B b; 

a = b.foo; // regular member variable access 

struct A *ap = &a; 
struct B *bp = &b; 

ap = (struct A *)bp; // cast the pointer 

ap = & b.foo;   // take a pointer from the member variable 
ap = & bp->foo;  // take a pointer from the member variable via a pointer 
+0

謝謝!我理解了一點點......但我只想知道'Object * el = calloc(1,size)'是什麼意思,當這樣做的正常方式是Object * el = calloc(1,sizeof(Object) );'',''el = proto;'之後在內存中發生了什麼,因爲el指向的內容大於proto需要的內容。 – linuxfish

+0

由於'calloc'用零字節填充內存,所以在內存中的結果將是proto的值,其後是零字節,直到size。在我的例子中,'struct A'是'struct B'的一個子集,所以'struct B'可以像使用'struct A'一樣使用。它們包含相同的前綴「int」。實質上,即使成員變量具有不同的名稱,struct B' *在開始處包含* struct A'。 –

+0

非常感謝快速回答!我想我得到了這個,非常感謝! – linuxfish