2014-01-22 14 views
4

不同的命名空間的我有以下結構的鏈式哈希表:分配不兼容的類型和使用C

typedef struct{ 
    char* phrase; 
    struct phrase_struct* next; 
}phrase_struct; 

我對這種結構殺到了指針實際上提到了可能不會有一個typedef定義但..但它編譯,所以我覺得這是有效的語法。我有幾個函數分配內存並操作指向下一個節點的指針next

考慮以下類型的指針和自動分配結構:

phrase_struct* ptr1

phrase_struct* ptr2

phrase_struct test_s;

如果我做了如下分配:

ptr1 = &test_s

ptr2 = test_s.next; < - 該指針將被設置爲在代碼

我會不斷地得到錯誤抱怨型的不相容分配別處NULL:

'=' : incompatible types - from 'phrase_struct *' to 'phrase_struct *'

然後它打我..我回憶起之前讀過關於typedef的命名空間和實際結構名稱是獨立的東西。


typedef struct test{ 
    char* phrase; 
    struct test* next; 
}phrase_struct; 

更改結構定義到這個固定所有的警告。

有人可以解釋這一點嗎?

+0

要考慮的另一個選項是:刪除'typedef',並將該類型稱爲'struct phase_struct'。但是如果你決定使用'typedef'(給這個類型一個更短的名字),那麼typedef的名稱可以和標籤相同:'typedef struct phase_struct {/ * ... * /} phase_struct;' –

回答

3

該定義

typedef struct{     // 1 
    char* phrase; 
    struct phrase_struct* next; // 2 
}phrase_struct;     // 3 

定義了3兩件事:

  1. 一種匿名結構
  2. 這是一個指向命名爲正向聲明的結構甲構件struct phrase_struct
  3. A的typedef nymous結構稱爲phrase_struct

當你表示一個普通phrase_struct,它指的是typedef。無論何時您參考struct typedef,它都指struct標記名稱空間內名爲phrase_struct的結構;這個結構已經被提出(在(2)中)並且是一個不完整的類型,但是它還沒有被完全定義。

該錯誤消息不幸混淆。什麼錯誤想說的是:

'=' : incompatible types - from 'struct phrase_struct *' to the typedef 
     'phrase_struct *' 

,因爲不確定的,前瞻性聲明的結構沒有任何關係已定義的typedef

的修復,因爲你發現,很簡單:不是定義匿名結構,使結構的名稱,並在成員定義指的是相同的名稱(在struct標籤的命名空間):

typedef struct phrase_struct{ // 1 
    char* phrase; 
    struct phrase_struct* next; // 2 
}phrase_struct;     // 3 

這定義:

  1. struct標籤命名空間命名struct phrase_struct的結構
  2. 具有指向struct phrase_struct實例的指針類型的成員(即,定義爲一個別名struct phrase_struct

在(1))

  • typedef命名phrase_struct中定義的類型,這是因爲標籤的命名空間(structunion,和enum)是從普通typedef命名空間分開這是令人困惑的。請參閱Difference between struct and typedef struct in C++?What is a typedef enum in Objective-C?

  • 1

    有了這個:

    typedef struct{ 
        char* phrase; 
        struct phrase_struct* next; 
    }phrase_struct; 
    

    你從來沒有定義struct phrase_struct,所以struct phrase_struct *是一個指向一個不完整的類型,你可能永遠無法定義。 phrase_struct這是一個匿名結構的typedef d名稱。這個匿名結構與struct phrase_struct不一樣,所以你的編譯器正確地指出指針的類型不同。

    當你說「編譯所以我認爲它是有效的語法」時,這是因爲你可以定義指向你還沒有定義的類型的指針,因爲所有的編譯器需要知道指針需要多少內存,它可以計算出來而不需要知道類型的細節。但是你必須先提供這種類型的定義,然後才能真正創建該類型的任何對象,並且在取消引用其指針以訪問其成員之前,等等。

    所以神祕的是你做了或者最初確實)具有有效的語法,但是該語法不能完成您認爲它的工作。

    相關問題