2014-01-25 44 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的問題離題太遠更好)