2011-02-27 106 views
0

我一直在試圖學習如何在C++中正確使用枚舉,並且我幾乎不能理解如何處理它們。我做了一個簡單的程序,改變交通信號燈使用枚舉和按位運算:正確使用枚舉C++

#include <iostream> 

enum lights 
{ 
    green = 1, 
    yellow = 2, 
    red = 4, 
    control = 7 
}; 

std::string change_light (std::string choice) 
{ 
    lights light; 
    int changed; 

    if (choice == "yellow") 
     light = yellow; 

    else if (choice == "red") 
     light = red; 

    else if (choice == "green") 
     light = green; 

    changed = control & light; 

    if (changed == red) 
     return "red"; 

    else if (changed == yellow) 
     return "yellow"; 

    else if (changed == green) 
     return "green"; 
} 

int main() 
{ 
    std::string choice = ""; 

    while (1) 
    { 
     std::cout << "What light do you want to turn on?" << std::endl; 
     std::cin >> choice; 
     std::cout << "Changed to " << change_light(choice) << std::endl; 
    } 

    return 0; 
} 

如何提高該程序,同時保持使用位操作和枚舉的?如果你能告訴我如何改進它,這將大大提高我對正確使用枚舉的理解。

感謝:d

+1

該函數並沒有真正做任何事情。它只是返回相同的字符串(如果它是其中一種顏色,否則未定義的行爲)。 - 爲什麼不嘗試從一種顏色切換到另一種顏色? – UncleBens 2011-02-27 11:52:41

+1

'changed = control&light;'與'changed = light;'相同,在這種情況下。實際上,函數change_light只是返回它的輸入。你的例子不是很強大。很難理解你想要做什麼。 – wimh 2011-02-27 11:52:58

+0

我只是爲了試驗枚舉而做了這個功能。我想知道如何在使用枚舉的同時使它更好。如果在使用枚舉時有辦法縮短它,請告訴我如何。我真的沒有得到使用枚舉。 – Lockhead 2011-02-27 11:58:04

回答

5

枚舉背後的整個想法是,你可以定義一組,給用戶和編譯器有一個變量是如何被使用的一些提示常量。

你的榜樣會更有意義,如果change_light功能會採取一個燈的說法是這樣的:

std::string change_light (lights choice) 
{ 
    switch(choice) 
    { 
    case red: return "red"; 
    case yellow: return "yellow"; 
    case green: return "green"; 
    } 
} 

這樣編譯器知道,該功能只需要一定的論據和你沒有得到的功能像「change_light」(「藍色」)的呼叫


因此,您使用枚舉來保護代碼的其餘部分不受錯誤參數值的影響。你不能直接從std :: in讀取一個枚舉,因爲它不知道任何關於你的枚舉。閱讀後,您應該將輸入轉換爲枚舉。事情是這樣的:

lights string_to_ligths(std::string choice) 
{ 
    if(choice == "red") return red; 
    if(choice == "yellow") return yellow; 
    if(choice == "green") return green; 
} 

從這裏開始,所有的交通燈相關的功能,只接受枚舉值,不需要檢查,如果請求值在有效範圍內。

+0

我試過了,但是在main()中的while循環中,我調用了change_light()並將一個字符串傳遞給它(選擇)。我嘗試使用cin將輸入提取到lights變量,但它不起作用。 – Lockhead 2011-02-27 13:17:31

+0

這只是讓我回到我原來所做的。可能意味着我沒有正確使用枚舉。那麼任何人都可以告訴我如何以及何時使用它們?我真的很困惑。 – Lockhead 2011-02-27 14:32:46

+1

'CASE'應該是'case' – 2011-02-27 14:53:02

2

枚舉只是具有有限值範圍的整數。

比方說,你會實現你的信號有一個int:

#define SEMAPHORE_STATE_RED 1 
#define SEMAPHORE_STATE_YELLOW 2 
#define SEMAPHORE_STATE_GREEN 3 
int semaphore_state; 

下面將通過就好了,雖然它打破了你的信號的語義:

semaphore_state = 10; 

與枚舉它贏得通過編譯器來捕獲錯誤。

這是更大的,如果你會使用開關來代替if/else語句的:

switch (state) 
{ 
    case SEMAPHORE_STATE_GREEN: /* bla */ break; 
    case SEMAPHORE_STATE_RED: /* bla */ break; 
    /* if state would be enum, compiler would catch that we are missing the SEMAPHORE_STATE_YELLOW case */ 
} 

當然還有枚舉的其他用途。例如,我個人更喜歡枚舉常量超過定義(從未實際使用枚舉類型本身)。這種情況也是唯一可以與很多麻煩一起按位操作共存的情況。

1

您似乎認爲與枚舉類型相關的數字很重要。事實上,這些數字根本不重要。枚舉類型的真正想法是巧妙地捕獲一個變量,該變量的狀態不是而是數字,並且也很難通過使用角色捕獲(例如玩卡套裝,指南針方向或周)。如果有的話,很少會爲任何枚舉值分配一個特定的數字 - 它是一個不屬於枚舉類型的一部分的設施(但它非常偶然有用,因此它被保留),並且更多地用於混淆開始的程序員比協助,而不應該被設想爲枚舉的組成部分 - 有些語言甚至不允許它(例如Modula-3,Haskell,Ocaml)。枚舉類型並不經常使用 - 它們的使用有點模糊,並且通常不會有用:它們增加了程序的清晰度,但不增強功能(與之對比,例如,如果沒有編程幾乎不可能!)並且實際上從來不需要這樣的。這意味着您編寫的代碼片段雖然顯示使用中的枚舉類型,但並未證明其有用性:枚舉類型在澄清某些較大程序的某個方面時有其用處,這種用法不容易表現出來。最好建議程序員忽略它們,因爲它們對初學者來說顯得毫無意義和困惑。這是因爲他們的目的很難證明 - 雖然他們很有用,但我向你保證!我再說一遍:他們提供清晰的表達,而不是權力。

+1

枚舉通常用作命名位標誌,所以在這種情況下,數值是最重要的。 – ildjarn 2011-05-12 20:04:13