2014-01-25 25 views
2

我有这样的枚举:结合2个枚举与数学运算符

enum bus { 
    MEDIA_BUS_UNKNOWN, 
    MEDIA_BUS_VIRTUAL = 1 << 1, 
    MEDIA_BUS_PCI = 1 << 2, 
    MEDIA_BUS_USB = 1 << 3, 
}; 

和:

enum bus get_bus(char *sys) 
{ 
    FILE *fd; 
    char file[PATH_MAX]; 
    char s[1024]; 

    if(!strcmp(sys, "/sys/devices/virtual")) 
     return MEDIA_BUS_VIRTUAL; 

    snprintf(file, PATH_MAX, "%s/modalias", sys); 
    fd = fopen(file, "r"); 
    if(!fd) 
     return MEDIA_BUS_UNKNOWN; 
    if(!fgets(s, sizeof(s), fd)) { 
     fclose(fd); 
     return MEDIA_BUS_UNKNOWN; 
    } 
    fclose(fd); 

    if(!strncmp(s, "pci", 3)) 
     return MEDIA_BUS_PCI; 
    if(!strncmp(s, "usb", 3)) 
     return MEDIA_BUS_USB; 

    return MEDIA_BUS_UNKNOWN; 

}

我想创建一个功能与PCI返回装置(S)或USB总线:

const char *get_device(const enum bus desired_bus) 
{ 
    enum bus bus; 
................................................... 
    for(i = 0; i < md->md_size; i++, md_ptr++) { 
     bus = get_bus(md_ptr->sys); 
     if((bus & desired_bus) == desired_bus) 
       return md_ptr->node; 
} 

并称之为函数返回设备(多个):

get_device(const enum bus desired_bus) 

如果请求是用于与PCI或USB总线类型的设备:

get_device(MEDIA_BUS_PCI | MEDIA_BUS_USB); 

它可以使用数学运算符,枚举?

回答

1

当然您也可以使用数学运算符,但我相信您正在寻找bitwise operations,对不对?在这种情况下,你enum成员值需要的两个电源,SOU你将能够做的测试是这样的:if(desired_bus & MEDIA_BUS_PCI)如果以前desired_bus |= MEDIA_BUS_PCI做的if将有MEDIA_BUS_PCI价值,所以iftrue意味着位。

代码示例:

enum bus { 
    MEDIA_BUS_UNKNOWN, 
    MEDIA_BUS_VIRTUAL = 1 << 1, 
    MEDIA_BUS_PCI = 1 << 2, 
    MEDIA_BUS_USB = 1 << 3, 
}; 
/* set flags */ 
desired_bus |= (MEDIA_BUS_PCI | MEDIA_BUS_USB); 

and then: 

     /* test if flag MEDIA_BUS_PCI was requested.. */ 
     if(desired_bus & MEDIA_BUS_PCI) 

在这情况下,没有设置,我们得到了一个0值符合我们的MEDIA_BUS_UNKNOWN值,我认为这是一个不错的平均误差。

编辑一个更完整的工作C的例子:

enum bus { 
    MEDIA_BUS_UNKNOWN, 
    MEDIA_BUS_VIRTUAL = 1 << 1, 
    MEDIA_BUS_PCI = 1 << 2, 
    MEDIA_BUS_USB = 1 << 3, 
}; 

enum bus get_bus(const char *sys); 

int main(int argc, char *argv[]) 
{ 
    const char *sym = argv[1]; 
    enum bus b = get_bus(sym); 

    if(b & MEDIA_BUS_VIRTUAL) 
     printf("MEDIA_BUS_VIRTUAL requested\n"); 
    if(b & MEDIA_BUS_USB) 
     printf("MEDIA_BUS_USB requested\n"); 
    return 0; 
} 

enum bus get_bus(const char *sys) 
{ 
    if(!strcmp("pci", sys)) 
     return MEDIA_BUS_VIRTUAL; 
    if(!strcmp("usb", sys)) 
     return MEDIA_BUS_USB; 
    if(!strcmp("pci&usb", sys)) 
     return MEDIA_BUS_VIRTUAL | MEDIA_BUS_USB; 
    return MEDIA_BUS_UNKNOWN; 
} 

如果你调用编译后的程序:

a.exe usb:将输出:

MEDIA_BUS_USB requested

a.exe "pci&usb"将输出:

MEDIA_BUS_VIRTUAL requested 
MEDIA_BUS_USB requested 

注意:您可能需要使用一种像unsigned而不是enum bus(即最高规模int)持有一套enum bus值。

+0

设置时desired_bus到MEDIA_BUS_PCI | MEDIA_BUS_USB并检查:如果((bus&desired_bus)== desired_bus)获得输出,如果总线是pci或usb,则不起作用。 – user935420

+0

@ user935420:发布实际使用过的代码(包括枚举定义)。但是这个注释中的代码中的desired_bus必须是枚举值之一。 –

+0

确定使用实际代码 – user935420

0

是的,但是对于您的情况,您需要确保枚举值的每个组合都是唯一的,并且很容易分解。要做到这一点,你应该让每个人的两个不同的力量:(然后你就可以通过编写如desired_bus & MEDIA_BUS_PCI测试匹配)

enum bus { 
    MEDIA_BUS_UNKNOWN = 1, 
    MEDIA_BUS_VIRTUAL = 2, 
    MEDIA_BUS_PCI = 4, 
    MEDIA_BUS_USB = 8, 
}; 

0

这是个人喜好的问题,但我觉得用枚举举行位掩码而误导。

我宁愿用#define s来做,以便能够轻松定义掩码组合。例如:

#define MEDIA_BUS_UNKNOWN 0x00 

#define MEDIA_BUS_GPU  0x10 
#define MEDIA_BUS_CPU  0x20 

#define MEDIA_BUS_VIRTUAL (0x1 | MEDIA_BUS_CPU) 
#define MEDIA_BUS_PCI  (0x2 | MEDIA_BUS_CPU) 
#define MEDIA_BUS_USB  (0x3 | MEDIA_BUS_CPU) 
#define MEDIA_BUS_AGP  (0x4 | MEDIA_BUS_GPU) 
#define MEDIA_BUS_PCIE (0x5 | MEDIA_BUS_GPU) 

#define MEDIA_BUS_PU_MASK 0x30 // to isolate the PU type 
#define MEDIA_BUS_TYPE_MASK 0x0F // to isolate the bus type 

typedef int bus_type; 

(一个相当愚蠢的例子,但我找不到不从OP的问题离题太远更好)