2013-02-23 2 views
0

여러 조건이 C/C++에서 처리되는 방식을 알고 싶습니다. 나는 잘 작동하는 몇 가지 코드를 가지고 있지만, 나는 열중 한 행운이 있다는 것을 염려하고있다. 나는 잡히지 않기를 바란다. 고려 : '조건 1'TRUE입니다여러 조건문

if ((/*condition1*/) || (/*condition containing invalid reference*/)) 
{ 
    // do something 
} 

너무 오래로, 두 번째 조건은 그 자체로 조건이 오류를 생성 할 경우에도 오류가 발생 나타나지 않습니다. 예를 들어 :

int main() 
{ 
    char string1[] = "StackOverflow"; 
    char *string2 = 0; 

    // (1) This will work because string1 is valid 
    if (strlen(string1) != 0) 
     printf("%s", string1); 

    // (2) This will cause an error 
    if (strlen(string2) != 0) 
     printf("%s", string2); 

    // (3) But this if(OR) works fine 
    if ((strlen(string1) != 0)||(strlen(string2) != 0)) 
     printf("no problem!"); 

    // (4) And of course this doesn't 
    if ((strlen(string2) != 0)||(strlen(string1) != 0)) 
     printf("I don't believe it!"); 

    return 0; 
} 

그것은 경우() '문제는'최초의 진정한 문에 정지 해,의 목록 OR 조건을 볼 수있는, 왼쪽에서 오른쪽으로 읽기, 무슨 일이 있어도 다음 없습니다. 그러나에 번호 (3) 변경 : 첫 번째 조건은 따라서 거짓 전체를 렌더링, 거짓 임에도 불구하고

if ((strlen(string1) == 0) && (strlen(string2) == 0) 

하는 것은 실패 할 것 - 즉 문제는 OR 예처럼 중단하지 않습니다.

일반화하기 위해, 나는 다음과 같은 관찰 :

if ((TRUE) or (INVALID)) -> no problem 

if ((FALSE) or (INVALID)) -> error 

if ((TRUE) and (INVALID)) -> error 

if ((FALSE) and (INVALID)) -> error // see the EDIT 

모든 경우에 보편적 될 것 이러한 결과는, 또는 그/플랫폼에 의존 컴파일러?

위의 규칙에 따라 코드를 작성할 필요가 없거나 조건 중 하나가 유효하지 않은 상황에 빠지지 마십시오.

나는 내 상사를 위해 몇 가지 오래된 코드를 사용하고 있으며 위의 (3)과 같은 예제로 흩어져 있습니다. 무효 조건을 피하기 위해 코드를 모두 잡아 코드를 적용하는 데는 상당한 시간이 걸릴 것입니다. (3)과 (4)는 if(string2 != 0) { // } 블록 안에 앉아서 쉽게 조정할 수 있지만, 실제로 가지고있는 코드에는 쉽지 않습니다.

는 편집 :

다시 확인하기 때문에, if ((FALSE) and (INVALID))은 참으로 오류없이 실행 않습니다. 나는 왜 그것이 전에 실패했는지 모른다. 처음에는 문제가 있었을 지 모르겠다. 나는 그것을 주술과 빈약 한 집중에 집어 넣을 것이다.

궁극적으로, 답변이 암시되었지만 축 어적으로 확인되지는 않았지만 단락 회로 평가 (위키 링크 덕분에!)에 대한 의지가 합법적 인 방법 인 것 같습니다. 어떤 코드를 다시 작성할 필요가 없기 때문에 기쁩니다! strlen 호출이 정의되지 않은 동작을 호출하므로

+4

[단락 회로 평가] (http://en.wikipedia.org/wiki/Short-circuit_evaluation)라고합니다. –

+2

'if ((FALSE) and (INVALID)) -> error'가 참이 아니라면, 두 번째 조건을 평가하지 않고 false로 평가됩니다. 당신이 typo'ed하고'&& '대신에'&'를 사용하지 않는 한. –

답변

0
if (strlen(string2) != 0) 
    printf("%s", string2); 

여기 string2 문자열이 아닙니다.

if ((strlen(string1) != 0)||(strlen(string2) != 0)) 

은 C에서 || 연산자 왼쪽 피연산자가 1 평가되면 오른쪽 피연산자를 평가하지 않도록 보장한다. 그리고 여기서 왼쪽 피연산자 ||1으로 계산되므로 정의되지 않은 동작 인 strlen(string2)이 호출되지 않습니다.

2

예 잘 알려진 동작이며 표준을 따르는 모든 C/C++ 컴파일러에서 작동합니다.제시는 이미 그의 주석에서 언급 한 바와 같이 단락이라고하며, 특히 포인터와 함께 꽤 자주 사용되는 것을 :

void func(int *ptr) 
{ 
    if(ptr && *ptr) { 
     // pointer is valid and integer that it points to is not 0 
    } 
} 

귀하의 마지막 문 :

if ((FALSE) and (INVALID)) -> error 

가 잘못 thow입니다. 그리고 일명 & &은 왼쪽이 거짓이면 오른쪽 피연산자를 평가하지 않습니다.

0

C와 C++ 모두에서 부울 식은 결과를 확인하자마자 평가를 중단합니다. 연산자는 항상 무언가가 true를 반환하는 즉시 평가를 중단하며, 왼쪽 부분이 우선합니다. & &은 false가 반환 될 때마다 멈 춥니 다.

오른쪽에 원하는 것을 넣을 수 있습니다. 평가하지 않습니다.

정의되지 않은 동작으로 "유효하지 않은"표현식을 사용했음을 명심하십시오. 작동하는 경우 어떤 일이 발생하는지 알 수있는 방법이 없습니다.

1

"단락 회로"라고하는 것은 C++의 보편적 인 기능입니다. 그것이 작동하는 방식은 (TRUE || anything) 항상 진실이 될 것이므로 표현이 더 이상 평가되지 않을 것입니다. 이것은 항상 false가 될 것이기 때문에 동일하게 적용됩니다 (FALSE & &).

유용 방법의 좋은 예 : 사용자가 0 들어가면,

int x = 0; 
cin >> x; 
if (x != 0 && 10/x == 2) { 
    // ... 
} 

X에이 체크하여, 10/0 따라서 0

으로 나눈 프로그램을 저장 발생하지

이 기능은 항상 & & 및 ||