2012-01-08 59 views
9

我想知道如何做到這一點:按位或(|)的函數參數

func(param1|param2|param3) 

,然後提取功能的價值,我已經在多種功能看到了這一點,或者是它更好地做到這一點:

func(param1, ...) 

我想在C++中這樣做,我正在考慮將函數的參數作爲enum中的值。

我該如何解決這個問題?

回答

15

參數1,參數2,參數3通常定義爲打開不同位的數字。 |是按位替代的運算符,這意味着它在單獨的位上工作。

在例如:

const int param1 = 0x01; 
const int param2 = 0x02; 
const int param3 = 0x04; 

當傳遞參數起作用你使前面定義則params的按位的替代方案。 在功能上,你不分解,但檢查指定的位時,使用逐結合:

void func(int arg){ 
    if(arg & param1) 
    // do something 
    if(arg & param2) 
    // do something else 
    // ... 
} 

func(param1 | param3); 
// "do something" will be done, 
// but "do something else" not. 
+0

你也可以這樣定義'INT param1and2 = 0x03時數;'它像'參數1 | param2'; – 2012-01-08 13:53:52

+0

應該注意的是,只有特定的參數模式才能恢復'|'參數,就像答案中提供的那樣。否則,這將是不可能的:'3 | 4'與'1 |相同6'。 – Vlad 2012-01-08 13:55:49

+0

謝謝你們! 這就是我最終做的paxdiablo建議 – DarkRoast 2012-01-08 17:37:45

11

假設你已經有值作爲獨立的位(二的冪),如:

#define IS_ON 0x01 
#define IS_LARGE 0x02 
#define IS_RED 0x04 

(或等值enumsconst int值,這取決於你想如何做他們 - 我用#define只是因爲這是我已經習慣了),你可以他們爲:

funcname (IS_ON | IS_RED); // passes in 0x05 

然後你提取他們喜歡的東西:

void funcname (int bitmask) { 
    if ((bitmask & IS_ON) == IS_ON) { // 0x05 & 0x01 -> 0x01 
     // IS_ON bit is set. 
    } 
    : 
} 

對於單位符,你可以逃脫的if (bitmask & IS_ON)形式,但你需要的全面檢查,如果你的符可能是多位值(例如,0到7的三位音量級別)。

+0

is_not_on_and_is_not_red的按位運算符組合是什麼?它會是'funcname(〜IS_ON |〜IS_RED);'? – ontherocks 2014-02-08 07:21:58

+0

明確的解釋,但你應該提及的位應該是2的冪。對 ? – 2016-07-21 07:54:26

+0

而不是常量'0x01',你可以使用'1 << 0','1 << 2','1 << 3'等。我發現那些更具可讀性。 – 2016-07-21 08:36:34

0

這是如何創建任意按鈕類型「消息框」功能的有用的例子:

enum Button 
{ 
    OK =  0x0001, 
    CANCEL = 0x0010, 
    YES =  0x0100, 
    NO =  0x1000 
}; 

void messagebox(char *text, int button) 
{ 
    char msg[256]; 
    strcpy(msg, text); 

    if ((button & Button::OK) == Button::OK) 
     strcat(msg, " [OK]"); 
    if ((button & Button::CANCEL) == Button::CANCEL) 
     strcat(msg, " [Cancel]"); 
    if ((button & Button::YES) == Button::YES) 
     strcat(msg, " [Yes]"); 
    if ((button & Button::NO) == Button::NO) 
     strcat(msg, " [No]"); 

    cout << msg << endl; 
} 

int main() 
{ 
    messagebox("salam", Button::OK | Button::CANCEL); 
    return 0; 
}