본문 바로가기

논리 연산자 Logical Operators 본문

💘 C++/연산자들

논리 연산자 Logical Operators

Hyonii 2022. 1. 3. 23:24

논리 연산자 (Logical operators)

관계 연산자(relational operator)는

특정 조건이 true 인지 false 인지를 테스트 할 수 있지만 한번에 하나의 조건만 테스트 할 수 있다.

그러나 한번에 여러가지 조건을 테스트 해야 하는 경우가 있다.

논리 연산자는 여러 조건을 테스트 할 수 있는 기능을 제공한다.

 

C++에는 세가지 논리 연산자가 있다.

Operator Symbol Form Operation
Logical NOT ! !x true if x is false, or false if x is true
Logical AND && x && y true if both x and y are true, false otherwise
Logical OR || x || y true if either x or y are true, false otherwise

 

논리 부정 (Logical NOT)

Logical NOT ( Operator ! )
Right operand Result
true false
false true

논리 부정 연산자 ( ! ) 연산자가 피연산자 true를 평가하면 false 가 된다.

반대로, false 를 평가하면 true 가 된다.

논리 부정 연산자는 bool 값을 반전시킨다.

 

Logical NOT

 

한 가지 주의할 점은 논리 부정 연산자는 우선순위가 매우 높다.

그러니 항상 괄호 ( ) 를 사용하여 의도를 분명하게 하는 것이 좋다.

 

논리 OR (Logical OR) - 논리합

논리 OR 연산자는 두 조건 중 하나가 true 인지 테스트 하는데 사용한다.

왼쪽 피연산자가 true로 평가되거나, 오른쪽 피연산자가 true로 평가되면 논리 OR 연산자 ( || )는 true를 반환한다.

 

Logical OR ( Operator || )
Left operand Right operand Result
false false false
false true true
true false true
true true true

 

주의해야할 점

 

실제로는 ==보다 not operator가 먼저 계산이 되서 문제가 생기니까 주의 해야함

두개가 다르다는 것을 표현하고 싶으면 

if (!(x == y)) 이렇게 괄호로 싸줘야 함

아니면 if(x ! = y)

 

논리연산자 OR 가 쓰이는 상황

#include <iostream>
using namespace std;

int main()
{
    int v = 1;
    
    if (v == 0 || v == 1)
        cout << "v is 0 or 1" << endl;
        
    return 0;
}

//This produces the result:
//v is 0 or 1

얘도 if 문으로 쪼갤 수 있다.

 

이렇게 쓸데없이 길어지면 보는 사람이 힘들다.&nbsp;

여러 조건에도 논리 OR 연산자를 사용할 수 있다.

초보 프로그래머는 논리 OR 연산자 || 와 bitwise OR 연산자 | 를 혼동하곤 하니까 주의해야 한다.

 

논리 AND (Logical AND) - 논리곱

논리 AND 연산자는 두 조건이 모두 참인지 여부를 테스트하는데 사용한다.

두 조건이 모두 true이면 논리 AND 연산자 ( && ) 는 true를 반환한다.

그렇지 않으면 false를 반환한다.

 

Logical AND ( Operator && )
Left operand Right operand Result
false false false
false true false
true false false
true true true

 

논리연산자 AND 가 쓰이는 상황

#include <iostream>
using namespace std;

int main()
{
    bool hit = true;
    int health = 10;
    
    if(hit == true && health < 20)
    {
        cout << "die" << endl;
    }
    else
        health -= 20;
        
    return 0;
}

//This produces the result:
//die

얘를 if 문 두개로 쪼갤 수 있다.

#include <iostream>
using namespace std;

int main()
{
    bool hit = true;
    int health = 10;
    
    if(hit == true)
        if(health < 20)
    	{
        	cout << "die" << endl;
   	}
    /*else
        health -= 20;
    */    
    return 0;
}

//This produces the result:
//die

이렇게 쪼갤 수 있지만 else 붙일 때 문제가 생길 수 있다. 오히려 더 복잡해진다.

관계연산자는 잘 아는데 논리연산자를 잘 몰라서 if문을 여러개로 쪼개서 쓰는 것 보다는

논리연산자를 사용하는게 훨씬 효율적이고 읽기도 편하고 수정하기도 편하다

 

논리 OR 연산자처럼 논리 AND 연산자도 여러 조건을 연결할 수 있다.

 

논리 XOR (Logical XOR C++에는 없음

Logical XOR ( Operator != )
Left operand Right operand Result
false false false
false true true
true false true
true true false

C++에는 XOR Operator 없다.

그래서 보통 x 와 y가 boolean 타입일 경우에 이렇게 쓰인다.

 

이런식으로 쓰인다.

 Logical AND Logical OR가 섞여 있을 때 

#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;
    
    cout << r1 << endl;
    cout << r2 << endl;
    
    return 0;
}

//This produces the result:
//1
//0

 

r1과 r2의 결과가 같은 것이라고 예상했지만 다르다는 것을 알 수 있다.

Logical AND가 Logical OR 보다 우선순위가 높기 때문이다.

 

단락 평가 (Short circuit evaluation)

논리 AND 연산자 ( && ) 가 true로 평가되려면 두 피연산자가 모두 true 여야 한다.

만약 첫번쨰 피연산자가 false로 평가되면,

논리 AND 연산자는 두번째 피연산자가 true 인지 false 인지와 관계없이 false를 반환한다.

이 경우를 단락 평가 (Short circuit evaluation)라고 하며 주로 최적화 목적으로 수행된다.

 

#include <iostream>
using namespace std;

int main()
{
    //short circuit evaluation
    int x = 1;
    int y = 2;
    
    if (x == 1 && y++ == 2)
    {
        //do someting
    }
    
    cout << y << endl;
    
    return 0;
}

//This produces the result:
//3

이 때 x 의 값을 2로 바꾸면 

#include <iostream>
using namespace std;

int main()
{
    //short circuit evaluation
    int x = 2;
    int y = 2;
    
    if (x == 1 && y++ == 2)
    {
        //do someting
    }
    
    cout << y << endl;
    
    return 0;
}

//This produces the result:
//2

다르게 나온다.

 

이렇게 다르게 나오는 이유는 

if문 안에 &&계산을 하려고 하는데

왼쪽에 있는 식 x == 1을 먼저 계산을 하고, 다음에 오른쪽에 있는 식 y++ == 2 를 계산을 하고,

왼쪽과 오른쪽이 각각 true냐 false냐 고려해서 전체적으로 true 냐 false냐 계산하는 과정을 거치게 된다.

 

이 때 AND operator &&는 왼쪽을 먼저 계산한 다음에 왼쪽이 false 가 되면 오른쪽을 계산 하지않는다.

어차피 왼쪽 false니까 and operator는 둘중에 하나가 false면 false니까 전체를 false로 return 해버리게 계산을 빨리 하려고한다. 그래서 오른쪽에 있는 y++가 계산이 안된다.

 

#include <iostream>
using namespace std;

int main()
{
    //short circuit evaluation
    int x = 2;
    int y = 2;
    y++;
    if (x == 1 && y == 2)
    {
        //do someting
    }
    
    cout << y << endl;
    
    return 0;
}

//This produces the result:
//3

이렇게 생각하고 코딩하는 경우가 꽤 많다.

능숙한 프로그래머들은 의도적으로 이걸 이용하기도 한다.

and operator 작동 방식 이해 못하면 문제가 될 수 있음.

short circuit evaluation 작동방식은 잘 숙지를 하고 있어야 한다.

 

#include <iostream>
using namespace std;

int main()
{
    bool x = true;
    bool y = false;
    
    //De Morgan's Law
    !(x && y);
    !x && !y;
    //윗줄과 아랫줄은 엄연히 다르다.
    //이게 드모르간의 법칙. 분배법칙이 적용되지 않는다.
    
    return 0;
}

이렇게 해야 같은게 된다
이렇게 해야 같은게 된다

논리 OR 연산자 처럼, 초보 프로그래머는 논리 AND 연산자 &&와 bitwise AND 연산자 & 를 혼동하곤한다.

이름에 AND 가 있더라도 다른 기능을 수행하므로 주의해야한다. 

Comments