首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将两个枚举与数学运算符结合起来

将两个枚举与数学运算符结合起来
EN

Stack Overflow用户
提问于 2014-01-25 03:17:57
回答 3查看 134关注 0票数 2

我有这样的祈祷:

代码语言:javascript
复制
enum bus {
    MEDIA_BUS_UNKNOWN, 
    MEDIA_BUS_VIRTUAL = 1 << 1,
    MEDIA_BUS_PCI = 1 << 2,
    MEDIA_BUS_USB = 1 << 3,
};

以及:

代码语言:javascript
复制
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或usb总线返回设备的函数:

代码语言:javascript
复制
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;
}

并调用此函数返回设备:

代码语言:javascript
复制
get_device(const enum bus desired_bus)

如果请求是针对具有pci或usb总线类型的设备:

代码语言:javascript
复制
get_device(MEDIA_BUS_PCI | MEDIA_BUS_USB);

是否可以使用数学运算符作为枚举?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-25 03:28:35

当然,你可以使用数学运算符,但我相信你是在找bitwise operations,对吧?在这种情况下,您的enum成员值需要是2的幂,所以您可以这样进行测试:if(desired_bus & MEDIA_BUS_PCI),如果以前的desired_bus |= MEDIA_BUS_PCI已经完成,if将有MEDIA_BUS_PCI值,所以iftrue,这意味着设置了位。

代码示例:

代码语言:javascript
复制
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)

如果没有设置它,我们将得到一个与我们的MEDIA_BUS_UNKNOWN值相匹配的0值,我认为这是一个很好的误差。

编辑--一个更完整的C示例:

代码语言:javascript
复制
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"将输出:

代码语言:javascript
复制
MEDIA_BUS_VIRTUAL requested
MEDIA_BUS_USB requested

注意:您可能需要使用像unsigned这样的类型,而不是使用enum bus (最大的大小是int)来保存一组enum bus值。

票数 1
EN

Stack Overflow用户

发布于 2014-01-25 03:27:28

是的,但是对于您的情况,您需要确保枚举值的每个组合都是唯一的,并且易于分解。要做到这一点,您应该让每一个都成为两个人的独特力量:

代码语言:javascript
复制
enum bus {
    MEDIA_BUS_UNKNOWN = 1,
    MEDIA_BUS_VIRTUAL = 2,
    MEDIA_BUS_PCI = 4,
    MEDIA_BUS_USB = 8,
};

(然后,您可以通过编写例如desired_bus & MEDIA_BUS_PCI来测试匹配。)

票数 0
EN

Stack Overflow用户

发布于 2014-01-25 03:38:28

这是个人品味的问题,但我发现用绞刑架来拿口罩很有误导性。

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

代码语言:javascript
复制
#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的问题太远,我就找不到更好的了)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21346168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档