24.4 논리, 비교, 시프트 연산자에 괄호 사용하기
산술 연산자와 마찬가지로 논리 연산자도 우선순위가 있고, 괄호로 묶을 수 있습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
bracket_logical_operator.c
#include <stdio.h> #include <stdbool.h> int main() { bool b1; b1 = (false || false) && !false || false; // 논리 연산자의 우선순위는 !,&& , || 순 printf("%d\n", b1); // 0: false AND true 이므로 0 return 0; }
실행 결과
0
논리 연산자의 우선순위는 !, &&, || 순입니다. 따라서 (false || false) && !false || false의 연산 순서는 다음과 같습니다.
- (false || false)
- !false
-
false && true
- (false || false) && !false
-
false || false
- (false || false) && !false || false
AND 연산자와 OR 연산자 중 어떤 것을 먼저 계산하더라도 OR 연산자의 특성 때문에 결과는 언제나 같지만 우선순위 규칙으로는 OR 연산자보다 AND 연산자가 높습니다.
비교 연산자를 사용할 때도 우선순위를 잘 따져야 합니다.
comparison_operator_precedence.c
#include <stdio.h> int main() { int num1; num1 = 5 == 5 < 10; // ==보다 <의 우선순위가 높음 printf("%d\n", num1); // 0 return 0; }
실행 결과
0
비교 연산자 중 ==보다 <의 우선순위가 높습니다. 따라서 5 < 10이 먼저 계산되어 1이 나오고, 1과 5가 같은지 비교합니다. 1과 5는 다르므로 최종 결과는 0이 나옵니다.
시프트 연산자와 산술 연산자를 섞어서 사용할 때도 연산자 우선순위에 주의합니다.
bitwise_shift_arithmetic_operator_precedence.c
#include <stdio.h> int main() { int num1 = 1; int num2 = 2; int num3; num3 = num1 << 2 + num2 << 1; // <<보다 +의 우선순위가 높음 printf("%d\n", num3); // 32 return 0; }
실행 결과
32
시프트 연산자와 산술 연산자 중 산술 연산자의 우선순위가 더 높습니다. 즉, <<보다 +가 먼저 계산됩니다. 따라서 2 + num2가 먼저 계산되어 결국에는 num1 << 4 << 1의 형태가 됩니다.
보통 num1 << 2 + num2 << 1; 이런 코드는 시험에서나 볼 뿐 실무에서는 다음과 같이 괄호로 계산 의도를 명확하게 나타냅니다.
bracket_bitwise_shift_arithmetic_operator.c
#include <stdio.h> int main() { int num1 = 1; int num2 = 2; int num3; num3 = (num1 << 2) + (num2 << 1); // +보다 << 연산을 먼저하기 위해 괄호로 묶어줌 printf("%d\n", num3); // 8 return 0; }
실행 결과
8
즉, (num1 << 2) + (num2 << 1)은 시프트 연산을 괄호로 묶었으므로 덧셈보다 먼저 계산됩니다.
지금까지 연산자 우선순위에 대해 배웠는데 내용이 조금 어렵고 복잡했습니다. 실무에서는 이렇게 복잡한 경우가 많지 않으니 걱정하지 않아도 됩니다. 연산자는 우선순위가 있고, 우선순위에 따라 결과가 달라진다는 점만 기억하면 됩니다. 특히 연산자 우선순위가 신경쓰이면 무조건 괄호를 사용하세요. 우선순위를 따져가며 읽어야 되는 코드보다는 괄호가 많더라도 의도가 명확한 코드가 좋습니다.