2013-09-29 105 views
0

我有這個枚舉在c什麼是c中枚舉的int值?

枚舉是否像Java中的0..n?

typedef enum tag_result 
{ 
    // Success: 
    succeeded = 0, 
    no_error = 0, 

    // General errors 
    general_errors, 
     err_failed, 
     err_no_memory, 
     err_invalid_argument, 
     err_aborted 
} result; 
+3

你爲什麼不簡單地嘗試它? – Maroun

+0

這是[Oracle Enum教程](http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html) –

+1

爲什麼downvotes?嘗試它是不夠的。許多C程序似乎都能工作,但實際上依賴於未指定的,未定義的或實現定義的行爲。 – pburka

回答

3

是。

事實上,當涉及到數/指數或 - 作爲Java調用它 - 序C更加靈活,你可以定義一個開始,甚至定義每個枚舉數:

int main(int argc, char** argv) 
{ 
    printf("RED: %d\n", (int) RED); 
    printf("GREEN: %d\n", (int) GREEN); 
    printf("BLUE: %d\n", (int) BLUE); 
    return 0; 
} 

enum colors { RED, GREEN, BLUE}; 

的輸出將是

RED: 0 
GREEN: 1 
BLUE: 2 

enum colors { RED = 4, GREEN, BLUE}; 

輸出將是

RED: 4 
GREEN: 5 
BLUE: 6 

enum colors { RED = 1, GREEN = 3, BLUE = 5}; 

輸出將是

RED: 1 
GREEN: 3 
BLUE: 5 
+0

使用%d打印枚舉不正確。您需要將該值轉換爲int。 – pburka

+0

@pburka謝謝指出,我糾正它。 – A4L

1

是否枚舉去0..N象Java?

是它

+0

大聲笑..很好的答案,+1。 – Maroun

0

是的,但是這是你可以輕鬆地打印出來值檢查

result r = general_errors; 
printf("%d\n", r); 
r = err_failed; 
printf("%d\n", r); 
r = err_no_memory; 
printf("%d\n", r); 
r = err_invalid_argument; 
printf("%d\n", r); 
r = err_aborted; 
printf("%d\n", r); 

將打印

1 
2 
3 
4 
5 
+0

嘗試通過反覆試驗來了解C是很危險的。 C有許多未定義或實現定義的區域。例如,上面的代碼錯誤地使用%d打印結果。結果可能與int不兼容。爲了正確,需要演員。 – pburka

+0

@pburka woot?大聲笑嘗試它,它顯示了我所說的。並通過跟蹤和錯誤學習**總是**最好的方式,這證明了它。給它一秒,並嘗試它,你看它通過並顯示整數值。在C#或Java中,你需要一個強制轉換。不在c –

+0

@NoIdeaForAName它適用於你的編譯器。但它不是可移植的C,因爲它依賴於實現特定的行爲。如果sizeof(result)> sizeof(int)它將不起作用。 – pburka

0

是。在C中,枚舉總是從0開始,除非明確指定另一個值。任何未指定的值將從最後指定的值單調增加。

請注意,枚舉只能保證是一個足夠大的整數類型來表示枚舉中的值。它可能不是int。一些C編譯器將使用char或小的枚舉。

0

是的,默認情況下,第一個枚舉數的值爲0.但是也可以在指定符中顯式設置枚舉數的值。任何後續的枚舉器必須具有最後一個枚舉器的值加1。

enum demo { 
    first, 
    second = 4, 
    third, 
    fourth 
}; 

這裏first將具有0的值,但剩餘的三個將具有值4,5,6,

0

Ç枚舉是整數。該語言只是提供了一些語法來進行int替換(以及編譯器可以執行的其他一些項目)。

如果你想要一個類似枚舉的Java,你需要創建一堆全局對象。由於C缺乏Java枚舉合同的強制執行,您需要儘可能實現它們。

因此,這在兩個方面使事情複雜化。現在你需要模擬一個對象並模擬枚舉(如果你想在c中使用類似Java的枚舉)。

對於模擬一個對象,有一些技術很好。關鍵是要及早戒菸只實現你需要的功能,因爲你添加更多的功能,就越難是:

typedef struct tag_result { 
    int enum_value; 
    char* enum_name; 
} result; 

result* getEnumByValue(int index); 

result* getEnumByName(char* name); 

,並在.c文件

// resize to match entries 
int enum_limit = 5; 
result enums[enum_limit]; 

// it is your responsibility to not duplicate values. 
enums[0].enum_value = 0; 
enums[0].enum_name = "invalid_argument"; 
enums[1].enum_value = 1; 
enums[1].enum_name = "no_memory"; 

result* getEnumByName(char* name) { 
    int index; 
    for (index = 0; index < enum_limit; index++) { 
    if (strcmp(enums[index].enum_name, name)) { 
     return enums[index]; 
    } 
    } 
    return 0; 
} 

result* getEnumByValue(int value) { 
     int index; 
    for (index = 0; index < enum_limit; index++) { 
    if (enums[index].enum_value == value) { 
     return enums[index]; 
    } 
    } 
    return 0; 
} 

現在,如果你想封裝,你可以將結構分成兩部分,一部分暴露,一部分隱藏。第一種技術是隻公開typedef struct s_result result,讓結構的佈局在.h中定義。起初有點棘手,但它保證沒有任何內容暴露在內,並提供了.c文件的完全訪問權限。如果你使用這種技術,你需要添加訪問器方法。

int getResultValue(result* item) { 
    return (*item).enum_value; 
} 

char* getResultName(result* item) { 
    return (*item).enum_name; 
} 

有些人進一步分析,有一個「公共」和「私人」的標題。一個結構指向另一個結構(由void *指針隱藏)。這個想法是通過不公開「私有」頭指針的類型來隱藏數據。自然地位縫合在一起,您需要了解在佈線構造,

result* new_resultEnum(int value, char* name) { 
    result* newItem = (result*)malloc(sizeof(struct s_result)); 
    (*newItem).private = (p_result*)malloc(sizeof(struct s_p_result)); 
    (*newItem).private.enum_value = value; 
    (*newItem).private.enum_name = name; 
    return newItem; 
} 

利用這樣的技術,可以很容易地通過C的函數指針添加構件的方法(雖然語法是一個挑戰)。

... added to the constructor above ... 
    (*newItem).getValue = result_getValue; 

公開暴露「getValue」方法。有一個警告。在C中傳遞「this」指針並不是一個好方法,因爲成員函數缺乏「知道」它們在結構中的能力,並且「知道」該結構在哪裏開始。是的,有解決方法,但他們開始花費更多的時間和金錢。我通常只是不打擾,這使得這樣的代碼很常見。

result* myresult; 
    (*myresult).getValue(myresult); 

雖然我希望你喜歡錶面更深的劃痕,但你應該比成員函數更早停下來。也許我應該早早停止比polymorphisim的實現更快:)

+0

而我甚至沒有得到多態類型的處理。 –

+0

C枚舉不是整數。根據C99規範的6.7.2.2#4,「每個枚舉類型應與char,有符號整數類型或無符號整數類型兼容,類型的選擇是實現定義的),但應能夠表示值在查點的所有成員中。「 – pburka

+0

我們中的一些人在99之前一直使用C,但感謝更新:) –