2

假設我有兩個布爾變量,並且我想根據它們的值完成不同的事情。什麼是最簡單的方法來實現這一點?基於兩個布爾變量的分支

變型1:

if (a && b) 
{ 
    // ... 
} 
else if (a && !b) 
{ 
    // ... 
} 
else if (!a && b) 
{ 
    // ... 
} 
else 
{ 
    // ... 
} 

變體2:

if (a) 
{ 
    if (b) 
    { 
     // ... 
    } 
    else 
    { 
     // ... 
    } 
} 
else 
{ 
    if (b) 
    { 
     // ... 
    } 
    else 
    { 
     // ... 
    } 
} 

變體3:

switch (a << 1 | b) 
{ 
case 0: 
    // ... 
    break; 

case 1: 
    // ... 
    break; 

case 2: 
    // ... 
    break; 

case 3: 
    // ... 
    break; 
} 

變4:

lut[a][b](); 

void (*lut[2][2])() = {false_false, false_true, true_false, true_true}; 

void false_false() 
{ 
    // ... 
} 

void false_true() 
{ 
    // ... 
} 

void true_false() 
{ 
    // ... 
} 

void true_true() 
{ 
    // ... 
} 

的變體3和4太棘手/複雜,一般的程序員?我錯過的其他變體?

+2

爲什麼你會想要做3或4?看起來很可怕:) – murrekatt

回答

13

第一種變體最清晰,最可讀的,但它可以進行調整:

if (a && b) { 
    // ... 
} else if (a) { // no need to test !b here - b==true would be the first case 
    // ... 
} else if (b) { //no need to test !a here - that would be the first case 
    // ... 
} else { // !a&&!b - the last remaining 
    // ... 
} 
+0

+1非常好... – fredoverflow

+0

非常好,乾淨! – murrekatt

+0

只要整個陳述不適合在一個屏幕上,它就變得非常難以理解。我根本沒有發現這一點。 –

4

您忘了:

if (a) a_true(b); 
else a_false(b); 

這可能是最好的選擇,當appliable,而當你真正需要4種不同的行爲。

如果你有2個以上的布爾,如果我有2^n個不像上面那樣分解好的不同行爲,我把它當作代碼氣味。那麼我可以想想:

enum { case1, case2, ... } 

int dispatch_cases(bool a, bool b, bool c, ..., bool z); 

switch (dispatch_cases(a, b, ..., z)) 
{ 
case case1: 
    ... 
}; 

但是沒有上下文,很難說這樣的複雜性是否有必要。

1

恕我直言,我會去variant 3。因爲我個人,當我檢查平等時,我不喜歡if/else。它明確指出只有4種可能性。

一個小修改爲:

inline int STATES(int X, int Y) { return (X<<1) | Y; } 
// ... 
switch (STATES(a,b)) 

爲了使它更花哨,你可以用enum取代0,1,2,3爲好。

enum States { 
    NONE, 
    ONLY_B. 
    ONLY_A, 
    BOTH 
}; 
+1

然而,它沒有清楚地說明那些東西。這就是我不喜歡它的原因。 –

+0

@Martinho,是的,這是真的。我們可以在那裏有一些東西。我試圖在編輯版本中傳達您的消息。 – iammilind

+0

「真」的定義不是零。它不一定是沒有額外工作的人,比如'(X?2:0)|(Y?1:0)' – IronMensan

1

對於只有兩個布爾值,他們中的任何一個都是好的和合理的。人們可以根據自己的口味來選擇。

但是,如果有兩個以上的布爾值,說布爾值,那麼我個人用的查找表去,我會做這樣的:

typedef void (*functype)(); 

//16 functions to handle 16 cases! 
void f0() {} 
void f1() {} 
//...so on 
void f15() {} 

//setup lookup table 
functype lut[] = 
{ 
    f0, //0000 - means all bool are false 
    f1, //0001 
    f2, //0010 
    f3, //0011 
    f4, //0100 
    f5, //0101 
    f6, //0110 
    f7, //0111 
    f8, //1000 
    f9, //1001 
    f10, //1010 
    f11, //1011 
    f12, //1100 
    f13, //1101 
    f14, //1110 
    f15 //1111 - means all bool are true 
}; 

lut[MakeInt(b1,b2,b3,b4)](); //call 

MakeInt()很容易寫:

int MakeInt(bool b1, bool b2, bool b3, bool b4) 
{ 
    return b1 | (b2<<1) | (b3 <<2) | (b4<<3); 
} 
+1

如果有兩個以上的布爾值,我試圖找出如何擺脫它們。 –

+0

@Alexandre:即使我會試圖擺脫它們。但是如果我失敗了?然後我會選擇這種方法。 – Nawaz