3.1.6.5 연산자 우선순위와 컴퓨터의 수식 표기법

1. 수학에서의 “식의 계산”과 우선순위

사칙연산(+, -, *, /)이 복잡하게 뒤섞인 수식을 만났을 때, 우리는 초등학교 때부터 배운 엄격한 수학적 약속인 식의 계산 순서(Order of Operations)를 따릅니다. 수학이야기 식에도 값이 있다고! (Value of Expressions)에서 배웠듯, 식을 계산할 때는 거대한 덩어리들을 먼저 묶어서 풀어내는 우선순위가 정해져 있습니다.

수학의 기본 계산 순서 (BODMAS / PEMDAS)

  1. 괄호 (Brackets / Parentheses)
  2. 지수/거듭제곱 (Orders / Exponents)
  3. 곱셈과 나눗셈 (Multiplication & Division) (왼쪽에서 오른쪽으로)
  4. 덧셈과 뺄셈 (Addition & Subtraction) (왼쪽에서 오른쪽으로)

예를 들어 $3 + 4 \times 2$ 라는 수식이 있을 때, 덧셈을 먼저 해서 $7 \times 2 = 14$ 를 만들면 완전히 틀린 답이 됩니다. 수학 규칙에 따라 곱셈을 먼저 방어막처럼 묶어서 $3 + (4 \times 2) = 11$ 로 계산해야 올바른 식의 값을 도출할 수 있습니다.

컴퓨터 프로그래밍 역시 수학의 이 위대한 규칙을 그대로 물려받았습니다. 하지만 파이썬에는 수학의 사칙연산 말고도 앞서 배운 비교 연산자(>, ==)나 논리 연산자(and, or), 대입 연산자(=) 등 수많은 기호가 섞여 있습니다.

연산자 우선순위 폭군 웹툰 강력한 왕을 상징하는 괄호 ( )가 평민 연산자들(+, -, *)을 제치고 가장 먼저 위풍당당하게 행진하는 웹툰입니다.

만약 여러분이 괄호 없이 모든 기호를 한 줄에 쏟아부으면, 파이썬 인터프리터는 내부적으로 정해진 연산자 우선순위 서열표에 입각하여 차근차근 계산을 해치워 나갑니다.

파이썬 핵심 연산자 서열표 (위로 갈수록 왕족, 아래로 갈수록 평민)

순위 연산자 기호 설명
1 (최우선) ( ) 괄호: 모든 규칙을 씹어먹는 절대적인 보호막 방패. 무조건 괄호 안쪽이 우주 1순위로 계산됩니다.
2 ** 거듭제곱 (지수)
3 +x, -x 단항 부호: 양수/음수를 나타내는 기호
4 *, /, //, % 곱셈, 나눗셈, 몫, 나머지
5 +, - 덧셈, 뺄셈
6 <, <=, >, >=, !=, == 비교 연산자: 계산 결과를 바탕으로 크거나 같은지를 필터링합니다.
7 not 논리 반전
8 and 논리 곱 (직렬)
9 or 논리 합 (병렬)
10 (꼴찌) = 할당 (대입) 연산자: 오른쪽의 길고 긴 모든 계산과 평가가 끝날 때까지 묵묵히 기다렸다가 마지막에 변수 상자에 집어넣습니다.

혼합 계산 실습

# 1. 산술 + 비교 + 논리가 섞인 끔찍한(?) 혼종 수식
x = 5
y = 10
# 괄호가 없어도 파이썬이 알아서 아래 순서대로 쪼갭니다:
# 1: 산술 (x*2 = 10), (y/2 = 5)
# 2: 비교 (10 > 5), (5 == 5) -> True, True
# 3: 논리 (True and True) -> True
# 4: 마지막으로 result 에 제일 마지막으로 담깁니다.
result = x * 2 > 5 and y / 2 == 5  
print("복합 수식 결과:", result)  # True

# 2. 괄호 ( ) 의 마법: 연산자 세계의 폭군!
# 거듭제곱(**)이 원래 더 세지만, 괄호가 쳐지면 평민인 덧셈이 먼저 실행됩니다!
normal_calc = 2 + 3 ** 2     # 2 + 9 = 11
magic_calc = (2 + 3) ** 2    # 5 ** 2 = 25
print("기본 우선순위:", normal_calc, "/ 괄호 강제:", magic_calc)

⚠️ 전문가의 조언 (Best Practice): 실무에서 프로그래머들은 컴퓨터가 아무리 서열표를 잘 안다고 해도, 저렇게 괄호 없이 길게 늘어쓰는 것을 극도로 혐오합니다. 코드의 가독성을 높이고 인간(자신과 동료)의 뇌가 헷갈려 에러를 내지 않도록, 애매할 때는 언제나 괄호 ( )를 듬뿍 사용하여 묶어주는 것이 훌륭한 코딩 습관입니다. ((x * 2) > 5) and ((y / 2) == 5) 처럼 말이죠.


3. 컴퓨터 내부의 수식 표기법 아키텍처 (Infix, Postfix, Prefix)

우리가 평소 수학 시간에 노트에 적는 3 + 4 와 같은 수식은 사람의 눈에 가장 읽기 편한 형태입니다. 하지만 CPU와 메모리로 구성된 컴퓨터의 내부 알고리즘에서 이를 해석(Parsing)하려면, 괄호 쌍을 추적하고 연산자 우선순위를 앞뒤로 확인해야 해서 대단히 비효율적입니다.

그래서 컴퓨터 과학자들은 괄호라는 복잡한 장치 없이도 수식의 우선순위가 완벽히 보장되는 혁신적인 수식 표기 배열법들을 발명했습니다. 컴퓨터 구조(Architecture)나 자료구조(Data Structure) 과목의 핵심이 되는 이 3가지 표기법을 살펴봅니다.

1) 중위 표기법 (Infix Notation) : 인간의 언어

  • 형태: 연산자가 두 개의 피연산자 가운데(In)에 위치합니다.
  • 예시: A + B * C
  • 특징: 우리 인간에게 가장 친숙하고 가독성이 뛰어납니다. 하지만 컴퓨터가 이를 풀려면 어느 연산자(+, *)를 먼저 할지 몰라 왔다 갔다 하며 괄호나 서열표를 체크해야 하는 복잡한 계산기(파서)가 필요합니다. 파이썬 코드 에디터에 적는 모든 수식은 중위 표기법입니다.

2) 전위 표기법 (Prefix / Polish Notation) : LISP의 영혼

  • 형태: 연산자가 피연산자들의 가장 앞(Pre)에 튀어나와 위치합니다. 폴란드 수학자 얀 우카시에비치가 고안하여 보통 폴리쉬 표기법이라고도 부릅니다.
  • 방식: “더해라! A와 B를” 처럼 동사(명령어)가 먼저 나오는 구조입니다.
  • 예시: + A * B C (의미: B와 C를 곱한 뒤, 그 결과에 A를 더해라!)
  • 특징: LISP나 Scheme 계열의 인공지능 탐색 함수형 프로그래밍 언어들이 이 표기법을 뼈대로 삼고 있습니다.

3) 후위 표기법 (Postfix / Reverse Polish Notation) : 스택(Stack) 머신의 심장

  • 형태: 연산자가 피연산자들의 가장 뒤(Post)에 따라붙습니다.
  • 방식: “A랑 B를… 더해라!” 처럼 재료를 먼저 던져놓고 늦게 지시하는 형식입니다.
  • 예시: A B C * + (의미: B와 C를 먼저 *로 묶어서 처리하고, 남은 A와 앞서 구한 덩어리를 + 묶어라!)
  • 특징: 괄호 기호 ( )가 아예 존재할 이유가 사라집니다! 보이는 순서(왼쪽 $\to$ 오른쪽)대로 ‘스택(Stack)’이라는 그릇 형태의 자료구조에 데이터를 넣었다(Push) 뺐다(Pop) 하면서 순서대로 연산자를 만나면 펑펑 계산만 하면 됩니다.
  • 실제 활용: 자바 가상 머신(JVM)의 바이트코드, HP 공학용 계산기, 그리고 화려한 PDF/프린터 출력용 언어인 어도비(Adobe)의 포스트스크립트(PostScript) 기술이 이 후위 표기법의 절대적인 연산 속도를 사용합니다.

💡 후위 표기법(Postfix) 스택 연산 시뮬레이션

수식 3 4 2 * + 가 컴퓨터 안의 그릇(Stack)에서 어떻게 처리되는지 상상해 봅시다.

  1. 3을 그릇에 넣습니다. [3]
  2. 4를 그릇에 넣습니다. [3, 4]
  3. 2를 그릇에 넣습니다. [3, 4, 2]
  4. * 기호를 만났습니다! 컴퓨터는 기뻐하며 그릇 맨 위 숫자 2개(42)를 빼내어 곱한 뒤($4 \times 2 = 8$), 다시 던져 넣습니다. [3, 8]
  5. + 기호를 만났습니다! 방금처럼 맨 위 2개를 빼내어 더합니다($3 + 8 = 11$). 최종 그릇엔 결과 [11] 값 하나만 남고 끝납니다. 이처럼 괄호의 방위 체계 없이 1차원으로 끝내버리는 경이로운 속도를 갖춥니다.

요약정리

파이썬 소스코드 창에서는 우리가 인간답게 괄호를 친 중위 표기법으로 수식을 넘겨주지만(예: a + (b * c)), 똑똑한 파이썬 인터프리터 컴파일러는 이 문장을 제일 먼저 분석하여 컴퓨터가 계산하기 편한 후위 표기법(추상 구문 트리)으로 번역하여 메모리 안에서 한 치의 오차도, 괄호의 얽힘도 없이 초고속으로 계산을 완료해 낸다는 사실을 기억해 두세요!


코딩 영단어 학습 📝

  • Precedence: 우선순위. (여러 연산자가 동시에 등장했을 때, 누구부터 먼저 처리할지 등급을 매겨놓은 공식 서열표를 뜻합니다.)
서브목차