20. 연산자 우선순위
1. 키워드
- 연산자 우선순위
2. 연산자 우선순위 알아보기
- C에는 다양한 연산자들끼리 우선순위가 정해져 있다.
- 연산자 우선순위를 모두 외울 필요는 없으며 필요할 때 찾아보면 된다.
- 보통 연산자의 계산 순서를
()
(괄호)로 명확하게 나타낸다.
3. 괄호 사용하기
- 먼저
35 + 1 * 2
를 계산해 보자.
#include <stdio.h>
int main()
{
int num1;
num1 = 35 + 1 * 2; // 1 * 2가 먼저 계산되므로 35 + 2가 됨
printf("%d\n", num1); // 37
return 0;
}
- 연산자 우선순위에 따라 곱셈이 덧셈보다 우선하므로
1 * 2
가 먼저 계산되어37
이 나온다. - 기본적으로 계산식은 우선순위가 높은 연산자가 가장 먼저 계산되고, 결합 방향에 따라 순서대로 계산된다.
+
,*
는 결합 방향이→
이므로 왼쪽에서 오른쪽 순으로 계산된다.
- 그럼
35 + 1
이 먼저 계산되도록 해보자.
#include <stdio.h>
int main()
{
int num1;
num1 = (35 + 1) * 2; // 괄호를 사용하여 35 + 1을 먼저 계산한 뒤 2를 곱함
printf("%d\n", num1); // 72
return 0;
}
- 연산자 우선순위가 낮지만 먼저 계산해야 할 식은
()
로 묶어준다. - 즉,
(35 + 1) * 2
는35 + 1
이 먼저 계산되어36
이 되고2
를 곱하여72
가 나온다. - 여기서
()
를 사용한 계산식의 계산 순서는 다음과 같다.
1] ()
를 사용한 연산자
2] 우선순위가 높은 연산자
3] 결합방향에 따라 순서대로 계산(+
, *
는 왼쪽에서 오른쪽)
- 보통 계산식의 의도를 명확하게 나타내기 위해 우선순위가 높은 연산자라도
()
로 묶어줄 때가 많다.
()
는 여러 번 겹쳐서 사용해도 된다.- 계산 결과는 달라지지 않지만 복잡한 식의 가독성을 높이기 위해 주로 사용한다.
4. 연산자의 결합 방향 알아보기
- 보통 연산자는
→
방향으로 계산을 하지만←
방향인 것들도 있다.
#include <stdio.h>
int main()
{
int num1 = 1;
int num2;
num2 = ++num1; // 변수를 먼저 평가하고 앞에 있는 ++을 계산
printf("%d\n", num2); // 2
return 0;
}
- 대표적으로 변수 앞에 붙는
++
와=
연산자가←
방향이다. ++num1
은num1
변수를 먼저 평가(계산)하고, 앞에 있는++
을 계산하여1
을 증가시킨다.num2 = ++num1;
에서 할당 연산자=
는 왼쪽에 있는 변수에 값이 들어가므로←
방향이다.
- 만약 다음과 같이 변수 여러 개를 연달아 할당한다면 맨 뒤에 있는
num1 = 10
부터 처리되어num1
에10
이 들어간 뒤←
방향으로 값이 차례대로 할당된다.
++
,--
와=
뿐만 아니라+
(양의 부호),-
(음의 부호),!
,~
등 변수나 숫자 앞쪽에 붙는 연산자도←
방향이다.- 단, 변수 뒤에 붙는
++
,--
는 연산 방향이→
이다.
5. 결합 방향이 다른 연산자와 괄호 사용하기
- 이번에는 결합 방향이 다른 연산자를 좀 더 많이 사용해 보자.
#include <stdio.h>
int main()
{
int num1;
int num2 = 3;
num1 = 10 + 2 / (5 - 3) * ++num2; // 괄호와 증가 연산자를 먼저 계산
printf("%d\n", num1); // 14
return 0;
}
10 + 2 / (5 - 3) * ++num2
에서 연산 순서는 다음과 같다.
1] (5 - 3)
2] ++num2
3] 2 / 2
2 / (5 - 3)
4] 1 * 4
2 / (5 - 3) * ++num2
5] 10 + 4
10 + 2 / (5 - 3) * ++num2
- 먼저 연산자 우선순위에 상관없이 괄호부터 먼저 계산한 뒤 연산자 우선순위 따라 순서대로 계산한다.
- 그리고
*
,/
는 결합 방향이→
이므로 왼쪽에서 오른쪽 순으로 계산하면 된다. - 여기서는
()
로 감싼(5 - 3)
이 먼저 계산된다. - 그리고 연산자 우선순위가 가장 높은
++
증가 연산자(앞)가 계산된 뒤*
,/
이 차례대로 계산된다. - 마지막으로 연산자 우선순위가 가장 낮은
+
가 계산되어14
가 나오게 된다.
6. 논리, 비교, 시프트 연산자에 괄호 사용하기
- 산술 연산자와 마찬가지로 논리 연산자도 우선순위가 있고,
()
로 묶을 수 있다.
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool b1;
b1 = (false || false) && !false || false; // 논리 연산자의 우선순위는 !, &&, || 순
printf("%d\n", b1); // false AND true 이므로 0
return 0;
}
// 0
- 논리 연산자의 우선순위는
!
,&&
,||
순이다. - 따라서
(false || false) && !false || false
의 연산 순서는 다음과 같다.
1] (false || false)
2] !false
3] false && true
(false || false) && !false
4] false || false
(false || false) && !false || false
- AND 연산자와 OR 연산자 중 어떤 것을 먼저 계산하더라도 OR 연산자의 특성 때문에 결과는 언제나 같지만 우선순위 규칙으로는 OR 연산자보다 AND 연산자가 높다.
- 비교 연산자를 사용할 때도 우선순위를 잘 따져야 한다.
#include <stdio.h>
int main()
{
int num1;
num1 = 5 == 5 < 10; // ==보다 <의 우선순위가 높음
printf("%d\n", num1); // 0
return 0;
}
- 비교 연사자 중
==
보다<
의 우선순위가 높다. - 따라서
5 < 10
이 먼저 계산되어1
이 나오고,1
과5
가 같은지 비교한다. 1
과5
는 다르므로 최종 결과는0
이 나온다.
- 시프트 연산자와 산술 연산자를 섞어서 사용할 때도 연산자 우선순위에 주의한다.
#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;
}
- 시프트 연산자와 산술 연산자 중 산술 연산자의 우선순위가 더 높다.
- 즉,
<<
보다+
가 먼저 계산된다. - 따라서
2 + num2
가 먼저 계산되어 결국에는num1 << 4 << 1
의 형태가 된다.
- 보통
num1 << 2 + num2 << 1;
과 같은 코드는 시험에서나 볼 뿐 실무에서는 다음과 같이()
로 계산 의도를 명확하게 나타낸다.
#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;
}
- 즉,
(num1 << 2) + (num2 << 1)
은 시프트 연산을()
로 묶었으므로 덧셈보다 먼저 계산된다.