연산자 우선순위와 결합 법칙
프로그래밍에서 하나의 표현식에 여러 종류의 연산자가 함께 사용될 때, 연산의 순서는 연산자의 우선순위와 결합 법칙에 따라 결정됩니다. C#에서 표현식을 평가할 때, 우선순위가 높은 연산자가 먼저 계산되며, 우선순위가 동일한 경우에는 결합 법칙(왼쪽에서 오른쪽, 또는 오른쪽에서 왼쪽)에 따라 계산 순서가 정해집니다.
C#의 주요 연산자 우선순위와 결합 법칙은 다음 표와 같습니다.
| 우선순위 | 연산자 | 결합 법칙 |
|---|---|---|
| 1 | () | 왼쪽에서 오른쪽 |
| 2 | !, ++, -- | 오른쪽에서 왼쪽 |
| 3 | *, /, % | 왼쪽에서 오른쪽 |
| 4 | +, - | 왼쪽에서 오른쪽 |
| 5 | >, <, >=, <= | 왼쪽에서 오른쪽 |
| 6 | ==, != | 왼쪽에서 오른쪽 |
| 7 | && | 왼쪽에서 오른쪽 |
| 8 | || | 왼쪽에서 오른쪽 |
| 9 | =, +=, -=, *=, /=, %= | 오른쪽에서 왼쪽 |
우선순위 1이 가장 높고 9가 가장 낮습니다. 전체적인 흐름으로 보면 괄호 > 산술 연산 > 관계 연산 > 논리 연산 > 대입 연산 순서로 우선순위가 결정됩니다.
복잡한 논리 표현식 평가
연산자 우선순위와 결합 법칙이 실제 코드에서 어떻게 적용되는지 확인해 보겠습니다. 아래 예제에서는 여러 종류의 연산자가 혼합된 복잡한 표현식을 평가합니다.
using System;
namespace OperatorPrecedenceExample
{
class Program
{
static void Main(string[] args)
{
// 1. 변수 선언 및 초기화
int num1 = 5, num2 = 10, num3 = 7;
bool evalResult;
// 2. 복합 표현식 계산
// 대입 연산자(=)의 우선순위가 가장 낮으므로 오른쪽의 논리 연산이 먼저 수행됨
evalResult = (num1 >= num2 || num1 - 1 == 4) && (num3 < num2);
// 3. 결과 출력
Console.WriteLine($"표현식 평가 결과: {evalResult}");
}
}
}
위 코드에서 표현식 (num1 >= num2 || num1 - 1 == 4) && (num3 < num2)의 실행 흐름은 다음과 같습니다.
- 대입 연산자의 우선순위가 가장 낮으므로, 우측의 논리 AND(
&&) 연산을 먼저 평가합니다. - 논리 AND 연산자는 왼쪽에서 오른쪽으로 결합하므로, 먼저 좌측 괄호 안의 논리 OR(
||) 연산을 수행합니다. - 괄호 내부에서
num1 >= num2(5 >= 10)는false가 되고,num1 - 1 == 4(5 - 1 == 4)는true가 되어 OR 연산의 결과는true가 됩니다. - 우측 괄호 안의
num3 < num2(7 < 10)는true가 됩니다. - 최종적으로
true && true가 되어 전체 표현식의 결과는true로 도출됩니다.
복잡한 표현식을 작성할 때는 가독성과 오류 방지를 위해 괄호 ()를 적극적으로 활용하여 연산 순서를 명확히 지정하고, 필요시 표현식을 여러 단계로 나누는 것이 좋습니다.
실전 예제: 윤년(Leap Year) 판별 로직
연산자를 활용한 실전 사례로 윤년을 판별하는 로직을 구현해 보겠습니다. 윤년은 양력에서 2월이 29일까지 있는 해를 의미하며, 날짜 및 시간 관련 데이터를 다룰 때 필수적으로 고려해야 하는 요소입니다.
윤년의 조건은 다음 두 가지 중 하나를 만족해야 합니다.
- 연도가 4로 나누어떨어지면서, 100으로는 나누어떨어지지 않는 경우
- 연도가 400으로 나누어떨어지는 경우
이 조건을 논리 연산자를 사용하여 하나의 표현식으로 구현할 수 있습니다.
using System;
namespace LeapYearChecker
{
class Program
{
static void Main(string[] args)
{
int inputYear;
bool isLeapYear;
Console.Write("판별할 연도를 입력하세요: ");
// 사용자 입력 처리 및 예외 방지
if (int.TryParse(Console.ReadLine(), out inputYear))
{
// 윤년 판별 조건식
// (4의 배수 AND 100의 배수가 아님) OR (400의 배수)
isLeapYear = (inputYear % 4 == 0 && inputYear % 100 != 0) || (inputYear % 400 == 0);
Console.WriteLine($"{inputYear}년은 윤년입니까? {isLeapYear}");
}
else
{
Console.WriteLine("유효한 숫자를 입력해 주세요.");
}
}
}
}
위 코드에서는 % (나머지) 연산자와 논리 연산자(&&, ||)를 조합하여 윤년 조건을 정확히 반영했습니다. 또한 int.TryParse를 사용하여 사용자의 잘못된 입력에 대비한 안정적인 구조로 개선되었습니다.