[英]Type Declarations in C ( Conceptual )
一般而言,該問題更多是概念性問題,而本質上不是編碼問題。 當我遇到這些代碼片段時,我很好奇,想知道它們是否有效。 或為什么基本上可以請別人給我一個解釋?
這是C語言中的一些類型聲明:
typedef struct Rec1 * Ptr1;
typedef struct Rec2 * Ptr2;
struct Rec1
{
int data;
Ptr2 next;
};
struct Rec2
{
double data;
Ptr2 next;
};
應該允許這些嗎? 他們被允許嗎? 為什么或者為什么不?
他們有效嗎?
原因:
前兩Ptr1
和Ptr2
創建為struct Rec1 *
和struct Rec2 *
類型定義。
因為它們是指針,而不是結構本身,所以它們將struct Rec1
和struct Rec2
設為不完整類型,並且它們只是將Rec2
設為遞歸類型(通常用於創建數據結構), Rec1
帶有指向Rec2
對象的指針。
應該允許他們嗎?
您還可以如何創建自引用結構?
簡短版本:
應該允許嗎? 是
它們是(轉發類型類型定義)嗎? 是。
為什么或者為什么不?
這是進行正向類型聲明的一種普遍接受的方式。 它允許聲明一個不完整的類型並在以后定義它。 在像這樣的簡單情況下,這沒什么大不了的,但是在更復雜的情況下,這絕對是必要的。
Linux或Darwin內核都相當廣泛地使用此技術來聲明內部內核結構,以允許在其自己的頭文件中定義數據類型,但允許在完全定義數據類型之前使用它。
如果沒有這種機制,就不可能定義復雜,相互依賴的數據類型。
根據語言標准,它們是有效的,因此應該允許。
現在,如果您問所有這些如何工作,這很簡單。
通常,指針只是內存地址。 如果對象由整數字節表示(每個字節都有唯一的地址),則可以在內存中指向任何對象。 我在這里說“整數”是因為您沒有指針來構造位字段(至少,您不能有一個指針不是指向不是從字節邊界開始並占據整數字節的指針) 。
因此, Ptr2
只是一個預先已知大小的指針類型(如果CPU的地址空間為0到4 GB,則32位地址足以尋址每個字節,而32位將是此CPU上的本機指針大小),並且您仍可以在struct Rec1
和struct Rec2
為此類指針分配空間,即使該指針指向的對象尚不知道,這也正是我們所討論的代碼中的內容。 Ptr1
和Ptr2
被定義為不完整的類型,這是它的正式名稱。
在語言中實現此類不完整指針類型的基本原理非常實用。 如果要創建鏈接列表或樹,則它們的元素或節點必須以某種方式指向與其鏈接的其他元素或節點。 從理論上講,您可以為最后一個元素(或葉節點)創建一個不同的元素/節點類型,然后為指向該元素的節點/節點類型創建一個,然后為指向該元素的節點/節點類型創建依此類推。 但是,如果您只有多個元素或節點,那么擴展性就不好。 如果您想要一百萬個該怎么辦? 定義一百萬個幾乎相同的類型充其量是不切實際的。 因此,該語言為您提供了避免這種情況的捷徑。 您也可以將next
指針聲明為void*
指針,但是隨后您需要將它們struct Rect1*
為struct Rect1*
或struct Rect2*
,並且此類代碼的維護和調試將容易出錯。 因此,那里的語言可以幫助您。
typedef只是其引用的實際類型的別名。 您可以將其視為宏,但是在編譯的預處理階段並不能替代它。
僅用 結構Rec1 *替換所有出現的Ptr1 即可產生有效的代碼,這是確認代碼是否有效的最簡單方法;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.