2012-08-27 156 views
1

我有相當複雜的if語句邏輯。我目前正在使用:C++嵌套如果語句可讀性

if(numerical_evaluation) { 

    if ((!boolOne && boolTwo) || !boolThree){ 
     //do stuff 
    } 
} 

其中boolOne,boolTwo和boolThree是邏輯運算(也許x < y或 'myObject-> getBool' 等)。

我不知道一個更好的方法來使這個易於閱讀,而不需要在第三個if語句中嵌套||條件。

我有困難的原因是or運算符使得它看起來像第三個if聲明可能是有保證的。

一個選擇就是做這個。

或者,我可以做類似

if(x <= y) { 

    bool boolFour = false; 
    if ((!boolOne && boolTwo)) 
     boolFour = true; 

    if (boolFour || !boolThree){ 
     //do stuff 
    } 
} 

甚至讓一個單獨的函數來嘗試驗證一切,或組合成一個單一的返回值?

或者,我可以嘗試以這種方式重組代碼,這可能需要大量的時間。

我的問題:什麼是格式化複雜if問題的最佳途徑 - 這不僅僅包括if (!A && B && C)變化更復雜的評價?當您將||語句與&&語句組合在一行中時,看起來事情變得無望而無法讀取(特別是當您對boolOne,boolTwo等進行復雜評估時)。 - Best way to format if statement with multiple conditions也適用同樣的原則嗎?或者在使用各種邏輯運算符時存在根本差異?

+0

這可能更適合[Programmers.SE](http://programmers.stackexchange.com/)。 – ildjarn

+0

爲什麼無法讀取?這是完全可讀的... – ForEveR

+0

這是主觀的,可能會被關閉。就我個人而言,我喜歡將邏輯封裝到描述函數中,所以最終的陳述就像'if(HasAccess()&& IsEditable()){...'。 – tenfour

回答

13

此:

bool boolFour = false; 
if ((!boolOne && boolTwo)) 
    boolFour = true; 

可以更清楚地表述爲:

bool const boolFour = !boolOne && boolTwo; 

通過給boolFour一個良好的,描述性的名稱,打破複雜的表達式的這一做法,並命名的子表達式能使代碼更具可讀性,更容易理解,並且更容易調試。

如果在多個地方使用複雜表達式,則應該使用函數來封裝公共邏輯。但是,如果僅在一個地方使用表達式,則最好在本地分解表達式並使用命名的常量變量來保持邏輯與其使用的位置接近。

+3

描述性命名和[德摩根定律](http://en.wikipedia.org/wiki/DeMorgan%27s_Law)的組合可以在表達式的可讀性方面創造奇蹟。 –

+0

這是一個非常好的方法,出於某種原因,我從來沒有想過要這樣做。 – enderland

4

編寫封裝組合布爾檢查的幫助函數。 E.G:

bool isEligibleForReduction(int age) { return age < 12 || age >= 60; } 
+0

只是一個脫離主題(和相當無用)評論在這裏......爲什麼不'年齡< 12 || age > 59'或爲此'年齡<= 11 ||年齡> = 60'? –

+0

因爲我認爲在人類語言中規則規定12歲以下的兒童和60歲或以上的成年人有資格獲得減免。當然你的建議也是正確的。 – StackedCrooked

+0

是的,這很奇怪,不是嗎?爲什麼不堅持一種比較形式?好吧。 –

0

如果可能的話我通常會做這樣的事情:

if(numerical_evaluation) { 

    meaningful_name = (!boolOne && boolTwo); 
    other_meaningful_name = !boolThree; 
    if (meaningful_name || other_meaningful_name){ 
     //do stuff 
    } 
} 
0
if (!numerical_evaluation) { 
    // nothing to do. 
} else if (!boolOne && boolTwo || !boolThree) { 
    // do whatever 
} 

當然,正如其他人所說,boolOneboolTwoboolThree是不是非常有幫助的名字。

0

最好的方法是善用白色空間。

if(numerical_evaluation && 
    (
     (!boolOne && boolTwo) || 
     !boolThree 
    ) 
) { 
     //do stuff 
} 

這不完全漂亮,但它很容易遵循。你也可以使用一個函數來隱藏if邏輯。

bool my_test(int numerical_evaluation, bool boolOne, bool boolTwo, bool boolThree) { 
    return 
     numerical_evaluation && 
     (
      (!boolOne && boolTwo) || 
      !boolThree 
     ); 
} 

if(my_test(numerical_evaluation, boolOne, boolTwo, boolThree)) { 
    // do stuff 
} 

記住,當它不是一個簡單的情況下,使用註釋給人們你在測試什麼(不需要徵求意見,只是解釋C++語法)的想法。即使他們可以閱讀你的if邏輯,但它可以讓他們仔細檢查它。良好的評論可以快速給人們一個概述你的程序和大部分的邏輯,而不用讀取不必要的細節或任何代碼。

+2

哦,我的。不不不。這不是更好。我很高興能夠維護一個5,000行的源文件,這個文件大量使用了這種複雜的「格式良好」表達式,這是一場災難。幾乎不可能調試。一旦你有兩到三個操作員混合級別,就很難跟蹤哪些操作員使用哪些操作數。只需將表達式分解爲代表每個子表達式的多個有名的變量。這樣的代碼是自我記錄,更容易調試,更容易理解。 –

+0

該方法已被建議。它不適用於布爾代數和邏輯簡化,這可能導致糟糕代碼的噩夢,荒謬地將太多的子表達存儲到變量中。使用網絡系統時,我並不總是喜歡使用這些變量。我想將此添加到對話中。這需要一點練習,但是如果名字很好,我可以更輕鬆地閱讀它。當我不做管理工作時,我個人保留了大約50,000行C++代碼,並且在性能情況下我只使用額外的變量。我的Oracle漏洞比我的多了10000倍。 – jbo5112

0

儘管這是一個性能建議,但複雜的布爾表達式有時可以更好地表示爲表查找。

複雜的東西,如:

if((a && !c) || (a && b && c)) 
{ 
    category = 1; 
} 
else if((b && !a) || (a && c && !b) 
{ 
    category = 2; 
} 
else if(c && !a && !b) 
{ 
    category = 3; 
} 
else 
{ 
    category = 0; 
} 

變爲:

static int categoryTable[2][2][2] = { 
    // !b!c !bc b!c bc 
    0,   3,  2,  2,  // !a 
    1,   2,  1,  1  // a 
}; 
... 
category = categoryTable[a][b][c]; 

代碼完成2頁614 & 615, 「代表複雜的表達式查找」。