2011-02-27 120 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