[20251210] 조건문/반복문

SmartBear·2025년 12월 10일

조건문

대부분의 프로그램은 데이터의 변화에 따라 변조해야 하는 로직이 다르게 된다.
즉, 특정 조건에 따른 분기가 발생하게 된다.
아래는 이러한 분기를 위한 문법인 if 나 switch 등에 대해 서술한다.

if / else if / else

다른 언어에서도 많이 사용되는 가장 기본적인 조건문 문법이다. 보통 if(조건식)으로 많이 사용된다. 조건은 한 가지만 나오라는 법은 없다. 한번에 여러가지 조건을 확인해야 하는 경우가 다반사 발생한다. 아래는 그러한 경우에 대한 간략히 표현한 내용이다.

if (조건식) {
    내부 코드
} else if (조건식) {
    내부 코드
} else if (조건식) {  // else if 는 여러개 사용 가능하다.
    내부 코드
} else {  // 위 조건들에 부합되지 않는 모든 내용에 대해 해당 조건문을 타게 된다.
    내부 코드
}

실습 코드

using System;


namespace Condition
{
    internal class Program
    {
        static void Main(string[] args)
        {
            const int initPlayerHp = 100;
            int playerHp = initPlayerHp;
            int damageTaken = 0;

            Console.WriteLine("\n몬스터와 전투 시작!");               
            Console.WriteLine("플레이어 체력: " + playerHp);
            Console.Write("몬스터 공격: ");
            if (!int.TryParse(Console.ReadLine(), out damageTaken))
            {
                Console.WriteLine("공격이 빚나갔다!!");
                return;
            }
            playerHp -= damageTaken;
            if (playerHp >= (int)(initPlayerHp * 0.7f))
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("아직 건강하다.");
                Console.ResetColor();
            }
            else if (playerHp >= (int)(initPlayerHp * 0.3f))
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("조심해라");
                Console.ResetColor();
            }
            else if (playerHp > 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("죽기직전!");
                Console.ResetColor();
            }
            else
            {
                playerHp = 0;
                Console.BackgroundColor = ConsoleColor.Red;
                Console.WriteLine("유다희");
                Console.ResetColor();
            }
            Console.WriteLine("플레이어 체력: " + playerHp);        
        }
    }
}

실행 화면

몬스터와 전투 시작!
플레이어 체력: 100
몬스터 공격: 40
조심해라
플레이어 체력: 60

switch

조건 자체가 특정 값에 대한 비교며 관련 분기가 많을 경우 Switch 문을 사용하는 경우도 많다.

switch (변수) 
{
    case 값1:  
        코드
        break;
    case 값2:
        코드
        break;
    ...
    default:
        코드
        break;
}

아레 if-elseswitch를 비교하는 간단한 예시를 통해 이해해보자.

if-else 문

int a = int.Parse(Console.ReadLine());
if (a == 1) Console.WriteLine("첫번째");
else if (a == 2) Console.WriteLine("두번째");
else if (a == 3) Console.WriteLine("세번째");
else Console.WriteLine("나머지");

switch 문

int a = int.Parse(Console.ReadLine());
switch (a) {
    case 1: 
        Console.WriteLine("첫번째");
        break;
    case 2:
        Console.WriteLine("두번째");
        break;
    case 3:
        Console.WriteLine("세번째");
        break;
    default:
        Console.WriteLine("나머지");
        break;
}

실습 코드

using System;


namespace Switch
{
    internal class Program
    {
        static void Main(string[] args)
        {
            const string SYSTEM = "SYSTEM";
            string playerName = "Hero";
            Console.Write("워프할 장소를 선택하세요 (1:마을, 2:던전, 3:상점) : ");
            int warpNum = int.Parse(Console.ReadLine());
            switch (warpNum)
            {
                case 1:
                    Console.WriteLine($"{playerName}: 마을 가자.");
                    Console.WriteLine($"{SYSTEM}: 환영합니다.");
                    break;
                case 2:
                    Console.WriteLine($"{playerName}: 던전 가자.");
                    Console.WriteLine($"{SYSTEM}: 조심하세요.");
                    break;
                case 3:
                    Console.WriteLine($"{playerName}: 상점 가자.");
                    Console.WriteLine($"{SYSTEM}: 뭘 사시겠어요?");
                    break;
                default:
                    Console.WriteLine($"{playerName}: 여긴 어디야.");
                    Console.WriteLine($"{SYSTEM}: 당신은 길을 잃었습니다.");
                    break;
            }
        }
    }
}

실행 화면

워프할 장소를 선택하세요 (1:마을, 2:던전, 3:상점) : 3
Hero: 상점 가자.
SYSTEM: 뭘 사시겠어요?

반복문

코드를 실행하다보면 상당히 많은 케이스로, 반복해서 출력하거나, 데이터를 입력해야 하는 경우가 발생한다.
가령 1부터 10까지 숫자를 출력하라는 코드가 있을 경우 이를 모두 Console.WriteLine을 이용하여 출력하는 것은 효율이 좋지 않다. 10번찍어도 되는데 만약 1000번이 되면?
이와 같이 동일한 동작을 여러번 진행해야 할 경우 반복문을 사용하게 된다.
대표적으로 while 문과 for문이 있다. 통틀어 Loop문이라고 하는 경우가 많다.

while / do-while

while 문에 대한 개인적인 경험(python 때의)으로는 주로 예측할 수 없는 횟수에 대한 Loop 나 EventDrivenLoop 를 실행할 때, 혹은 Process를 계속 띄워 놓고 있어야 하는 상황에서 자주 사용하였다. 보통 아래와 같은 형태로 쓴다.

while (조건문) {
    실행되어야 할 코드
}

아래 간단한 실습 코드를 보자.

실습 코드

using System;


namespace Loop
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int cnt = 1;
            while(cnt <= 10)
            {
                Console.WriteLine($"{cnt} 번째 실행");
                cnt++;
            }
        }
    }
}

실행 화면

1 번째 실행
2 번째 실행
3 번째 실행
4 번째 실행
5 번째 실행
6 번째 실행
7 번째 실행
8 번째 실행
9 번째 실행
10 번째 실행

do while 과의 차이점?

간단히, 실행되어야 할 코드가 조건보다 먼저 실행되느냐, 나중에 실행되는냐의 차이이다.
while조건문부터 확인을 하며, do-while실행되어야 할 코드부터 실행 후 조건을 확인한다.

실습 코드

using System;


namespace Loop
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // while vs do-while
            while (false)
            {
                Console.WriteLine("while문 안쪽");
            }
            do
            {
                Console.WriteLine("do-while문 안쪽");
            } while (false);
        }
    }
}

실행 화면

do-while문 안쪽

break / continue

반복문에 의해 코드가 진행될 시, 반복을 멈추거나 불필요한 코드를 실행하지 않아야하는 경우가 많이 발생한다.
반복을 멈출 때는 break를, 불필요한 코드를 실행하지 않아야 하는 경우에는 continue를 사용한다. break는 감이 빠르게 오지만 continue는 빠르게 오지 않을 수 있다. continue를 사용하게 되면 continue위의 코드는 실행이 되지만 continue아래의 코드는 모두 SKIP되고 다시 반복을 하게 된다.

실습 코드

using System;


namespace Loop
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Break, Continue            
            int input = 0;
            while (true)
            {
                Console.Write("입력 (0, 1) : ");
                input = int.Parse(Console.ReadLine());
                if (input == 0)
                {
                    Console.WriteLine("반복문 종료");
                    break; // 반복문 종료
                }
                else if (input == 1)
                {
                    Console.WriteLine("다음 반복문으로 이동");
                    continue; // 다음 반복문으로 이동
                    Console.WriteLine("이 출력문은 실행되지 않습니다.");
                } else
                {
                    Console.WriteLine("0 또는 1만 입력하세요.");
                }
            }            
        }
    }
}

실행 화면

입력 (0, 1) : 1
다음 반복문으로 이동
입력 (0, 1) : 1
다음 반복문으로 이동
입력 (0, 1) : 1
다음 반복문으로 이동
입력 (0, 1) : 0
반복문 종료

for

반복 횟수가 정해진 반복문은 while문보다 for문이 많이 사용된다. 특히, while문은 true조건과 같이 사용해 무한반복으로 사용하는 경우가 많으며, 조건식을 잘못하여 서도 무한반복이 일어나는 경우가 많다. 이때 강제로 프로세스를 종료하지 않는 이상 계속 프로그램이 돌아가는 문제가 발생한다. 때문에 의도상 무한반복을 구현하지 않는 경우는 for문을 사용하는 것이 일반적이다.

for (변수초기화; 조건; 증감연산) {
    실행되는 코드
}

일반적으로 위와 같이 사용된다.

실습 코드

using System;


namespace Loop
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int firstValue = 0;
            int secondValue = 0;
            int sumValue = 0;

            Console.Write("첫번째 숫자를 입력하세요: ");
            firstValue = int.Parse(Console.ReadLine());
            Console.Write("두번째 숫자를 입력하세요: ");
            secondValue = int.Parse(Console.ReadLine());
            if (firstValue >= secondValue) 
            {
                Console.WriteLine("첫번째 숫자는 항상 두번째 숫자보다 작아야합니다.");
                return;
            }
            for (int i = firstValue; i <= secondValue; i++)
            {
                sumValue += i;
            }
            Console.WriteLine("{0}부터 {1}까지의 합은 {2}입니다.", firstValue, secondValue, sumValue);
        }
    }
}

실행 화면

첫번째 숫자를 입력하세요: 3
두번째 숫자를 입력하세요: 10
3부터 10까지의 합은 52입니다.

이중 while/for 문

당연한 이야기지만 Loop문은 내부에 또 다른 Loop를 두어 다중 구조를 만들 수 있다.
가장 어려워(!?)하며 재밌게 해볼 만한 별찍기가 좋은 예시이다.

실습 코드

using System;


namespace Loop
{
    internal class Program
    {
        static void Main(string[] args)
        {// 블록 시작
            int floor = 20;
            for (int i = 1; i <= floor; i++)
            {
                for (int j = 1; j <= floor - i; j++) Console.Write(" ");                
                for (int j = 1; j <= (2 * i) - 1; j++) Console.Write("*");
                Console.WriteLine();
            }
        }// 블록 끝
    }
}

실행 화면

                   *
                  ***
                 *****
                *******
               *********
              ***********
             *************
            ***************
           *****************
          *******************
         *********************
        ***********************
       *************************
      ***************************
     *****************************
    *******************************
   *********************************
  ***********************************
 *************************************
***************************************

이중 혹은 다중 Loop문 사용시 유의 사항

다중 Loop문을 사용할 경우 실행되는 시간은 많이 길어질 수 있다.
간단한 예시로,

for (int i=0; i < 10; i++>) {
    for (int j=0; j < 10; j++>) {
        ...
    }
}

위 반복문을 실행하면 2개의 반복문이며 하나당 10번씩 돌아가 총 100번이 반복된다.
여기서 하나의 반복문을 추가해보자.

for (int i=0; i < 10; i++>) {
    for (int j=0; j < 10; j++>) {
        for (int k=0; k < 10; k++>) {
            ...
        }
    }
}

이것은 10 ^ 3 인 1000번이 실행될 것이다.

이러한 것을 선형 시간 복잡도라고 하며, 이렇게 많은 다중 구조가 되는 코드는 좋지 않은 코드가 된다.
선형 시간 복잡도 참고 자료 블로그지만 잘 정리되어있다

profile
Python Dev with Infra -> Game Programmer

0개의 댓글