16. 논리 연산자
1. 키워드
- 논리 연산자
- 단락 평가(Short-circuit Evaluation)
2. 논리 연산자 사용하기
- 논리 연산자는 조건식이나 값을 논리적으로 판단하기 때문에 논리 연산자는
if
조건문에서 조건식을 판단할 때 주로 사용한다.
- 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 연산자는 두 값이 모두 참이어야 참이므로 첫 번째 값이 거짓이면 두 번째 값은 확인하지 않고 바로 거짓으로 결정한다.
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 연산자는 값, 변수, 함수 앞에
!
를 붙여서 사용한다. !
는 참은 거짓으로, 거짓은 참으로 논릿값을 뒤집는다.- 따라서
0
은1
로,1
은0
이 된다. - 그리고 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
미만이면 첫 번째 조건을 만족하지 않으므로 단락 평가에 따라 두 번째 조건은 검사하지 않는다.
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;
}
// 거짓
// 참
// 거짓
- 변수에
1
과0
을 할당한 뒤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) &&
와 같이num1
이0
인지 검사하면 에러를 예방할 수 있다. - 즉,
&&
연산자에서 첫 번째 조건이 만족하지 않으면 두 번째 조건은 검사하지 않는 특성을 이용한 것이다. - 단락 평가는 논리 연산자로 된 조건 검사뿐만 아니라 사칙 연산 수행에도 적용된다.
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
- https://dojang.io/mod/page/view.php?id=153
- https://dojang.io/mod/page/view.php?id=154
- https://dojang.io/mod/page/view.php?id=155
- https://dojang.io/mod/page/view.php?id=156
- https://dojang.io/mod/page/view.php?id=157
- https://dojang.io/mod/page/view.php?id=158
- https://dojang.io/mod/page/view.php?id=159