2012-08-27 5 views
1

if 문에 대한 논리가 상당히 복잡합니다. 내가 현재 사용하고 있습니다 : boolOne, boolTwo 및 boolThree는 논리 연산이다C++ 중첩 된 If 문 읽기 어려움

if(numerical_evaluation) { 

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

(아마도 x < y 또는 'myObject-> getBool'등).

|| 조건을 세 번째 if 문 내에 중첩하지 않으면이 방법을 쉽게 읽을 수있는 방법을 모른다.

내가 어려움을 겪고있는 이유는 or 연산자가 제 3의 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 const boolFour = !boolOne && boolTwo; 

이름 표현식 수를, 좋은, 설명하는 이름 복잡한 식을 깨는이 방법을 boolFour을 제공함으로써 및 :

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

만큼 더 명확하게 표현 될 수있다 코드를 훨씬 읽기 쉽고, 이해하기 쉬우 며, 디버그하기가 훨씬 쉽습니다.

여러 위치에서 복잡한 표현식을 사용하는 경우 함수를 사용하여 공통 논리를 캡슐화해야합니다. 표현식이 한 곳에서만 사용되는 경우 표현식을 로컬에서 분리하고 명명 된 const 변수를 사용하여 로직을 사용 된 위치에 가깝게 유지하는 것이 바람직합니다.

+3

설명이 포함 된 이름과 [De Morgan 's Law] (http://en.wikipedia.org/wiki/DeMorgan%27s_Law)는 표현의 가독성에 대해 궁금해 할 수 있습니다. –

+0

이것은 정말 좋은 접근 방법입니다. 어떤 이유로, 나는 결코 생각하지 않았습니다. – enderland

4

결합 된 부울 검사를 캡슐화하는 도우미 함수를 작성하십시오. 이자형.g :

if(numerical_evaluation) { 

    meaningful_name = (!boolOne && boolTwo); 
    other_meaningful_name = !boolThree; 
    if (meaningful_name || other_meaningful_name){ 
     //do stuff 
    } 
} 
+0

여기에 댓글을 달았습니다. (꽤 쓸모가 없습니다.) 왜 '나이 < 12 || age > 59'이나 그 문제에 대해 '나이 <= 11 || 60 세 이상? –

+0

나는 인간의 언어로 규칙이 12 세 미만의 어린이를 말하고 60 세 이상의 성인은 감량 자격이 있다고 가정하기 때문에. 귀하의 제안은 물론 정확합니다. – StackedCrooked

+0

예, 이상하지 않습니까? 왜 비교의 한 형태를 고수하지 않습니까? 오 잘. –

0

나는 보통 일 같은 것은 할 것이다 가능합니다.

0
if (!numerical_evaluation) { 
    // nothing to do. 
} else if (!boolOne && boolTwo || !boolThree) { 
    // do whatever 
} 
다른 사람이 말했듯이 물론

, boolOne, boolTwoboolThree 매우 도움이 이름없는 :

bool isEligibleForReduction(int age) { return age < 12 || age >= 60; } 
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++ 코드를 유지 관리하며 성능 사례에서는 추가 변수 만 사용합니다. 저는 오라클 버그에 대해 10,000 배 이상의 시간을 잃었습니다. – 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), "복잡한 표현식에 대한 대체 테이블 조회"와 같은

뭔가 복잡.