wellcome_공부일기

C++ | 03.06 논리 연산자(Logical operator) 본문

프로그래밍/C++

C++ | 03.06 논리 연산자(Logical operator)

ma_heroine 2020. 5. 18. 22:40

* 해당 글은 홍정모님의 따라 배우는 C++을 공부한 토대로 작성되었습니다.

 

<목차>

1. 논리 연산자(Logical operator)

2. 논리 연산자(Logical operator) 주의사항

3. Short circuit evaluation

4. De Morgan’s law

5. C++에서 XOR 사용하기(To be continued)

6. Mixing ANDs and ORs

 

 

논리 연산자(Logical operator)

논리 연산자(Logical operator)는 true 혹은 false인 것을 묻는 Boolean 값으로 구분하기 때문에 이해가 어렵지는 않습니다.

 

논리 연산자의 종류

//Logical NOT

bool x = true;

cout << !x << endl; //output: 0

 

//Logical AND
 
bool x = true;
bool y = false;

cout << (x && y ) << endl; //output: 0

bool hit = true;
int health = 10;

//output: die
if ( hit == true && health < 20)
{
    cout << "die" << endl;
}
else
    health -= 20;

- AND 논리 연산자는 &&가 두개로, & 한개는 비트-와이즈 연산자입니다.

- 관계 연산자인 비교( == )는 true 혹은 false 값을 가집니다.

 

//Logical OR 

bool x = true;
bool y = false;

cout << (x || y ) << endl; //output: 1

 

논리 연산자(Logical operator) 주의사항

- 단순하고 명확하게 사용

#include <iostream>
using namespace std;

int main()
{
    int x = 5;
    int y = 7;

    if( x != y)//우선순위가 낮음 !은 대입보다 높음 불리언임 ! 그래서 항상 두가지가 같다고 나옴 그냥 x != y
    {
        cout << "x does not equal y" << endl;
    } else
        cout << "x equals y" << endl;
    return 0;

}

- x와 y가 같지 않다는 것을 표현할 때, 괄호를 사용하지 않는 이상, ( !x == y )로 표현하게 되면 !은 ==보다 우선순위가 높기 때문에, x,y가 항상 같다고 나옵니다.

- !은 불리언으로 컴퓨터는 0이 아니면 모두 true로 인식하기 때문에 항상 두가지가 같다고 출력됩니다.

- x != y )처럼 사용하여 더 단순하고 명확하게 표현해야 합니다. 

 

 

- 논리 연산자를 통한 간결한 코드 예시

#include <iostream>
using namespace std;

int main()
{

    int v = 1;

    if (v==0)
        cout << "v is 0 or 1" << endl;
    if (v==1)
        cout << "v is 0 or 1" << endl;

    return 0;

}

#include <iostream>
using namespace std;

int main()
{

    int v = 1;

    if (v==0 || v ==1)
        cout << "v is 0 or 1" << endl;

    return 0;

}

 

 

Short circuit evaluation

위와 비슷하게, 만약 logical OR이 첫번째 연산자가 true라면, OR 전체의 조건은 true로 평가되어지고, 두번째 피연산자는 평가되지 않습니다. 

 

Short circuit evaluation을 복잡한 상황에서 사용하게 되면, 의도한 결과가 나오지 않으므로 주의 깊게 사용해야 합니다.

if (x == 1 && ++y == 2)
    // do something

- 만약 x가 1과 같지 않다면, 전체 조건은 false가 되어야 합니다. 

- 그렇게 된다면, ++y는 계산/평가되지 않습니다.

- 따라서, x가 1로 평가될 경우에만 y가 증가하게 되는데, 이것은 아마도 프로그래머가 의도한 것이 아닐 수도 있습니다.

 

예시 코드

#include <iostream>
using namespace std;

int main()
{
  int x = 1;
  int y = 2;
  
  if(x == 1 && y++ == 2)
  {
      //do something
  }

  cout << y << endl; //output: 3

  return 0;
}


 

 

※ 주의

단락 평가(Short circuit evaluation)은 Logical OR과 Logical AND가 하나의 피연산자를 평가하지 않을 수 있습니다.

그래서 이러한 연산자와 함께 부작용이 발생할 수 있는 식은 사용하지 않는게 좋습니다.

 

 

때때로 Logical AND 연산자(&&)와 Bitwise AND 연산자(&), 그리고 OR도 혼동할 수 있으니 주의바랍니다.

 

Logical AND : &&       Logical OR : ||  

Bitwise AND : &         Bitwise OR : | 

 

 

De Morgan’s law

많은 프로그래머들은 !(x && y)이 !x && !y와 같을 거라는 생각을 하는데, logical NOT(!)에는 분배법칙이 적용되지 않습니다.

De Morgan’s law(드 모르간 법칙)은 logical NOT의 경우 어떻게 분배하는지 아래와 같이 보여줍니다.

 

!(x && y) is equivalent to !x || !y
!(x || y) is equivalent to !x && !y

 

다른 말로, logical NOT을 분배법칙을 할 때, logical AND을 logical OR로 바꾸는 역전 상황이 일어납니다.

이는 복잡한 수식을 좀 더 읽기 쉽게 만들어 유용합니다.

 

 

Mixing ANDs and ORs

#include <iostream>
using namespace std;

int main()
{
   bool v1 = true;
   bool v2 = false;
   bool v3 = false;

   bool r1 = v1 || v2 && v3;
   bool r2 = (v1 || v2) && v3;
   bool r3 = v1 || (v2 && v3); 


   cout << r1 << endl; //output: 1
   cout << r2 << endl; //output: 0


    return 0;

}

- 하나의 식에서 logical AND과 logical OR을 섞어 쓴다면, 괄호를 사용하여 표현해야 합니다. 

- logical &&가 ||보다 우선순위가 높기 때문에, 의도한 결과 값과 다르게 나올 수 있습니다. 

 

 

 

 

Comments