我有这个枚举:
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或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);
可以将数学运算符用于枚举吗?
答案 0 :(得分:1)
当然你可以使用数学运算符,但我相信你正在寻找bitwise operations,对吧?在这种情况下,您enum
成员的值必须是2的幂,您可以像这样进行测试:if(desired_bus & MEDIA_BUS_PCI)
如果先前desired_bus |= MEDIA_BUS_PCI
已完成if
}将具有MEDIA_BUS_PCI
值,因此if
为true
,表示该位已设置。
代码示例:
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示例:
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
值。
答案 1 :(得分:0)
是的,但对于您的情况,您需要确保每个枚举值组合都是唯一的,并且很容易分解。要做到这一点,你应该让每个人都有两个明显的力量:
enum bus {
MEDIA_BUS_UNKNOWN = 1,
MEDIA_BUS_VIRTUAL = 2,
MEDIA_BUS_PCI = 4,
MEDIA_BUS_USB = 8,
};
(然后您可以通过撰写例如desired_bus & MEDIA_BUS_PCI
来测试匹配。)
答案 2 :(得分:0)
这是个人品味的问题,但我发现使用枚举来控制位掩码而不是误导。
我宁愿用#define
来做,以便能够轻松定义蒙版组合。例如:
#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的问题,我找不到更好的方法)