Skip to content

16. 논리 연산자


1. 키워드

  • 논리 연산자
  • 단락 평가(Short-circuit Evaluation)


2. 논리 연산자 사용하기

  • 논리 연산자는 조건식이나 값을 논리적으로 판단하기 때문에 논리 연산자는 if 조건문에서 조건식을 판단할 때 주로 사용한다.


001


  • C에서는 논릿값 거짓은 0, 참은 0이 아닌 값이며 보통 1을 사용한다.


3. AND 연산자 사용하기

  • 먼저 AND 연산자 &&부터 알아보자.


#include <stdio.h>

int main()
{
    printf("%d\n", 1 && 1); // 1 AND 1은 참
    printf("%d\n", 1 && 0); // 1 AND 0은 거짓
    printf("%d\n", 0 && 1); // 0 AND 1은 거짓
    printf("%d\n", 0 && 0); // 0 AND 0은 거짓

    printf("%d\n", 2 && 3); // 2 AND 3은 참

    return 0;
}

// 1
// 0
// 0
// 0
// 1


  • AND 연산자는 &&처럼 & 기호를 두 개 붙여서 사용하며 하나만 사용하면 AND 비트 연산자가 되므로 주의한다.
  • &&는 두 값이 모두 참이어야 결과가 참이 나온다.
  • 따라서 1 && 1만 참이고 나머지는 모두 거짓이다.
  • 그리고 C에서는 0이 아닌 모든 값이 참이므로 2 && 3도 참이며 결과는 1이 출력된다.
  • 논리 연산에서 중요한 부분이 단락 평가인데, 단락 평가는 첫 번째 값만으로 결과가 확실할 때 두 번째 값은 확인(평가)하지 않는 방법을 말한다.
  • 즉, AND 연산자는 두 값이 모두 참이어야 참이므로 첫 번째 값이 거짓이면 두 번째 값은 확인하지 않고 바로 거짓으로 결정한다.


printf("%d\n", 0 && 1); // 첫 번째 값 0이 거짓이므로 두 번째 값 1은 확인하지 않고 거짓으로 결정


4. OR 연산자 사용하기

  • 이번에는 OR 연산자 ||를 알아보자.


#include <stdio.h>

int main()
{
    printf("%d\n", 1 || 1); // 1 OR 1은 참
    printf("%d\n", 1 || 0); // 1 OR 0은 참
    printf("%d\n", 0 || 1); // 0 OR 1은 참
    printf("%d\n", 0 || 0); // 0 OR 0은 거짓

    printf("%d\n", 2 || 3); // 2 OR 3은 참

    return 0;
}

// 1
// 1
// 1
// 0
// 1


  • OR 연산자는 ||처럼 | 기호를 두 개 붙여서 사용하며 하나만 사용하면 OR 비트 연산자가 되므로 주의한다.
  • ||는 두 값 중 하나만 참이라도 결과가 참이 나온다.
  • 따라서 1 || 1, 1 || 0, 0 || 1 모두 참이고, 0 || 0만 거짓이다.
  • 그리고 C에서는 0이 아닌 모든 값이 참이므로 2 || 3도 참이며 결과는 1이 출력된다.


  • OR 연산자는 두 값 중 하나만 참이라도 참이므로 첫 번째 값이 참이면 두 번째 값은 확인하지 않고 바로 참으로 결정한다.


printf("%d\n", 1 || 1); // 첫 번째 값 1이 참이므로 두 번째 값 1은 확인하지 않고 참으로 결정
printf("%d\n", 1 || 0); // 첫 번째 값 1이 참이므로 두 번째 값 0은 확인하지 않고 참으로 결정
printf("%d\n", 2 || 3); // 첫 번째 값 2가 참이므로 두 번째 값 3은 확인하지 않고 참으로 결정


5. NOT 연산자 사용하기

  • 이번에는 NOT 연산자 !를 사용해 보자.


#include <stdio.h>

int main()
{
    printf("%d\n", !1); // NOT 1은 거짓
    printf("%d\n", !0); // NOT 0은 참

    printf("%d\n", !3); // NOT 3은 거짓

    return 0;
}


  • NOT 연산자는 값, 변수, 함수 앞에 !를 붙여서 사용한다.
  • !는 참은 거짓으로, 거짓은 참으로 논릿값을 뒤집는다.
  • 따라서 01로, 10이 된다.
  • 그리고 C에서는 0이 아닌 모든 값이 참이므로 !3의 결과는 0이 된다.


6. 조건식과 논리 연산자 사용하기

  • 값뿐만 아니라 조건식 자체도 논리 연산자로 판단할 수 있다.


#include <stdio.h>

int main()
{
    int num1 = 20;
    int num2 = 10;
    int num3 = 30;
    int num4 = 15;

    printf("%d\n", num1 > num2 && num3 > num4); // 양쪽 모두 참이므로 참
    printf("%d\n", num1 > num2 && num3 < num4); // 앞만 참이므로 거짓

    printf("%d\n", num1 > num2 || num3 < num4); // 앞만 참이므로 참
    printf("%d\n", num1 < num2 || num3 < num4); // 양쪽 모두 거짓이므로 거짓

    printf("%d\n", !(num1 > num2)); // 참의 NOT은 거짓

    return 0;
}

// 1
// 0
// 1
// 0
// 0


  • 네 값을 두 값씩 묶어서 비교 연산자로 대소 관계를 비교한 뒤 논리 연산자로 참, 거짓을 판다했다.
  • 변수만 있으면 알아보기 어려우니 각 변수 값으로 바꿔서 살펴보자.


1] 20 > 10 && 30 > 15

  • 양쪽 모두 참이므로 AND 연산자의 결과는 참이다.

2] 20 > 10 && 30 < 15

  • 20 > 10만 참이고, 30 < 15는 거짓이므로 AND 연산자의 결과는 거짓이다.

3] 20 > 10 || 30 < 15

  • 20 > 10이 참이므로 OR 연산자의 결과는 참이다.

4] 20 < 10 || 30 < 15

  • 양쪽 모두 거짓이므로 OR 연산자의 결과는 거짓이다.

5] !(20 > 10)

  • 참을 NOT 연산자로 뒤집었으므로 결과는 거짓이다.


  • 비교 연산자와 논리 연산자가 연달아서 나오면 알아보기가 어렵다.
  • 따라서 다음과 같이 ()(괄호)를 사용하여 의도를 명확하게 나타내는 것이 좋다.


printf("%d\n", (num1 > num2) && (num3 > num4));
printf("%d\n", (num1 > num2) && (num3 < num4));

printf("%d\n", (num1 > num2) || (num3 < num4));
printf("%d\n", (num1 < num2) || (num3 < num4));


  • 예를 들어 && 연산자는 19세 이상, 65세 미만을 가려낼 때 사용할 수 있다.


(age >= 19) && (age < 65)


  • age 변수가 19 미만이면 첫 번째 조건을 만족하지 않으므로 단락 평가에 따라 두 번째 조건은 검사하지 않는다.


7. if 조건문과 논리 연산자 사용하기

  • 이제 if 조건문에 논리 연산자를 사용해 보자.


#include <stdio.h>

int main()
{
    int num1 = 1;
    int num2 = 0;

    if (num1 && num2) // num1과 num2가 모두 참인지 검사
        printf("참\n");
    else
        printf("거짓\n"); // num1만 참이므로 거짓이 출력됨

    if (num1 || num2)   // num1과 num2 둘 줄 하나가 참인지 검사
        printf("참\n"); // num1이 참이므로 참이 출력됨
    else
        printf("거짓\n");

    if (!num1) // num1을 반대로 뒤집음
        printf("참\n");
    else
        printf("거짓\n"); // 참을 뒤집었으므로 거짓이 출력됨

    return 0;
}

// 거짓
// 참
// 거짓


  • 변수에 10을 할당한 뒤 if 조건문 안에서 논리 연산자를 사용했다.
  • 여기서 num1에는 1, num2에는 0이 들어있으므로 AND 연산자의 결과는 거짓이며 OR 연산자의 결과는 참이다.
  • 또한, num1에 저장된 1을 뒤집었으므로 결과는 거짓이다.


  • if 조건문에서 논리 연산자를 사용하면 단락 평가에 따라 동작이 결정된다.
  • 다음 if 조건문에서 && 연산자는 첫 번째 값이 거짓이면 두 번째 값은 검사하지 않고 거짓으로 결정하므로 else의 코드가 실행된다.
  • 그리고 || 연산자는 첫 번째 값이 참이면 두 번째 값은 검사하지 않고 참으로 결정하므로 if의 코드가 실행된다.


int num1 = 0;
int num2 = 1;

if (num1 && num2) // 첫 번째 값이 거짓이면 두 번째 값은 검사하지 않고 거짓으로 결정
    printf("참\n");
else
    printf("거짓\n"); // 거짓 출력

num1 = 1;
num2 = 0;
if (num1 || num2)   // 첫 번째 값이 참이면 두 번째 값은 검사하지 않고 참으로 결정
    printf("참\n"); // 참 출력
else
    printf("거짓\n");


단락 평가의 활용

  • && 연산자의 단락 평가를 활용하면 문제가 발생하는 코드를 미리 예방할 수 있다.


int num1 = 0;
int num2 = 10;

if ((num1 != 0) && (num2 / num1) < 20) // num1이 0이면 나눗셈 연산을 하지 않음.
    printf("참\n");
else
    printf("거짓\n");


  • 정수를 0으로 나누면 에러가 발생하지만 나눗셈 연산 전에 (num1 != 0) &&와 같이 num10인지 검사하면 에러를 예방할 수 있다.
  • 즉, && 연산자에서 첫 번째 조건이 만족하지 않으면 두 번째 조건은 검사하지 않는 특성을 이용한 것이다.
  • 단락 평가는 논리 연산자로 된 조건 검사뿐만 아니라 사칙 연산 수행에도 적용된다.


8. 삼항 연산자에 논리 연산자 사용하기

  • if 조건문뿐만 아니라 삼항 연산자에서도 논리 연산자를 사용할 수 있다.


#include <stdio.h>

int main()
{
    int num1 = 1;
    int num2 = 0;

    printf("%s\n", num1 && num2 ? "참" : "거짓"); // 삼항 연산자에서 AND 연산자 사용
    printf("%s\n", num1 || num2 ? "참" : "거짓"); // 삼항 연산자에서 OR 연산자 사용

    return 0;
}

// 거짓
// 참


  • printf 함수 안에서 삼항 연산자를 사용하여 값을 출력했다.
  • num1에는 1, num2에는 0이 들어있으므로 AND 연산자의 결과는 거짓, OR 연산자의 결과는 참이다.

References