본문 바로가기
ZAION/C++

[이것이 C#이다]Ch.05 코드의 흐름 제어하기 - 1

by 우기37 2024. 1. 30.

## 목차

1) 분기문

2) 반복문

 

 

 

#1 분기문

분기문은 프로그램의 흐름을 조건에 따라 여러 갈래로 나누는 흐름 제어 구문입니다.

C#에서는 한 번에 단 하나의 조건만 평가할 수 있는 if문과 한 번에 여러 개의 조건을 평가할 수 있는 switch문을 제공합니다.

 

 

1. if, else, else if

if문에서 사용하는 조건식은 true 또는 false의 값을 가지는 bool 형식이어야 합니다. 이 조건식이 참인 경우에만 if 문 뒤에 따라오는 코드가 실행됩니다. 거짓이면 아무 일도 일어나지 않습니다.

 

if (조건식)
	참인_경우에_실행할_코드;

 

if문에서 조건식이참인 경우에 실해할 코드가 여러 줄인 경우 다음과 같이 중괄호 { 와 } 를 사용해서 코드 블록을 만들어 붙이면 됩니다.

 

if (조건식)
{
	// 참인 경우에
    // 실행할
    // 코드
}

 

아래 예시처럼 if문의 조건식이 false로 평가되면 별도의 조건 검사 없이 바로 '홀수'를 출력하는 코드로 프로그램의 흐름이 이동합니다. 그렇게되면 코드를 작성하는 수고도 줄고, 프로그램도 효율적으로 동작합니다.

 

int a = 10;

if ((a % 2) == 0)
	Console.WriteLine("짝수");
    
if ((a % 2) != 0)	// 분기문의 나쁜 예
	Console.WriteLine("홀수");
    
if ((a % 2) == 0)
	Console.WriteLine("짝수");
else			// 분기문의 옳은 예
	Console.WriteLine("홀수");

 

if ~ else문을 이용하면 프로그램의 흐름을 두 갈래로 나눌 수 있지만, 더 다양한 조건식을 사용하고 싶을 때는 else if 절이 도움을 줄 수 있습니다. else if는 if 문처럼 조건식을 가지며, if 문에 종속되어 사용됩니다.

 

int a = -10;

if (a < 0)
	Console.WriteLine("음수");
else if (a > 0)
	Console.WriteLine("양수");
else
	Console.WriteLine("0");

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.IfExam
{
    class IfElseExam
    {
        public void Main()
        {
            Console.WriteLine("숫자를 입력하세요: ");

            string input = Console.ReadLine();
            int number = Int32.Parse(input);

            if (number < 0)
                Console.WriteLine("음수");
            else if (number > 0)
                Console.WriteLine("양수");
            else
                Console.WriteLine("0");

            if (number % 2 == 0)
                Console.WriteLine("짝수");
            else
                Console.WriteLine("홀수");
        }
    }
}

 

 

 

 

2. if 문 중첩해서 사용하기

분기문이나 반복문같은 흐름 제어문은 또 다른 흐름 제어문을 중첩해서 사용할 수 있습니다.

유독 if 문과 for문 등은  같은 종류의 흐름 제어문을 자주 중첩해서 사용하는 편입니다.

 

아래 실습 예체 처럼 if 문 안에 다른 if 문을 넣고, 새로 넣은 if 문 안에 또 다른 if 문을 넣고.. 이런 식으로 얼마든지 프로그램의 흐름을 '갈기갈기' 찢어놓을 수 있습니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.IfExam
{
    class IfIfExam
    {
        public void Main()
        {
            Console.Write("숫자를 입력하세요: ");

            string input = Console.ReadLine();
            int number = Convert.ToInt32(input);

            if (number > 0 )
            {
                if (number % 2 == 0)
                    Console.WriteLine("0보다 큰 짝수");
                else
                    Console.WriteLine("0보다 큰 홀수");
            }
            else
            {
                Console.WriteLine("0보다 작거나 같은 수");
            }
        }
    }
}

 

 

 

3. switch 문

switch 문은 조건식의 결과가 가질 수 있는 다양한 경우를 한 번에 평가하고 프로그램의 흐름을 가를 때 사용합니다.

 

// switch 절
switch (조건식)
{
	// switch 절
	case 패턴1 :	// <- swirch 레이블
    // 실행할 코드
    	break;	// <- break 문
    case 패턴2 :
    // 실행할 코드
    	break;
    case 패턴3 :
    // 실행할 코드
    	break;
    default 패턴4 :
    // 실행할 코드
    	break;
}

 

switch 문은 switch 키워드로 시작하며, 따라오는 괄호 안에 조건식을 입력받습니다. 그리고 조건식이 어떤 switch 레이블의 패턴과 일치하는지를 검사하고, 그 레이블 아래에 있는 코드를 실행합니다. break 문은 실행 중인 코드 불록의 바깥으로 프로그램의 흐름을 옮깁니다. 즉, case 절이나 default 절에 사용된 break 문은 각 switch 절에서 실행중이던 흐름을 switch 문 바깥으로 옮깁니다.

 

그리고 필요에 따라 break문 대신 goto나 return, throw와 같은 점프문을 사용하는 것이 문법적으로 허용됩니다.

 

[실습]

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.SwitchExam
{
    class SwitchExam
    {
        public void Main()
        {
            Console.WriteLine("요일을 입력하세요.(일,월,화,수,목,금,토): ");
            string day = Console.ReadLine();

            switch (day)
            {
                case "일":
                    Console.WriteLine("Sunday");
                    break;
                case "월":
                    Console.WriteLine("Monday");
                    break;
                case "화":
                    Console.WriteLine("Tuesday");
                    break;
                case "수":
                    Console.WriteLine("Wednseday");
                    break;
                case "목":
                    Console.WriteLine("Thursday");
                    break;
                case "금":
                    Console.WriteLine("Friday");
                    break;
                case "토":
                    Console.WriteLine("Saturday");
                    break;
                default:
                    Console.WriteLine($"{day}는(은) 요일이 아닙니다.");
                    break;
            }
        }
    }
}

 

 

switch 문과 패턴 매칭

switch 레이블의 패턴에는 상수와 형식을 비롯해서 관계, 논리, 등등 C#이 지원하는 다양한 패턴을 적용할 수 있습니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.SwitchExam
{

    class SwitchExam_2
    {
        public void Main()
        {
            string s = Console.ReadLine();
            object obj = null;
            if (int.TryParse(s, out int out_i))
                obj = out_i;
            else if (float.TryParse(s, out float out_f))
                obj = out_f;
            else
                obj = s;

            switch (obj)
            {
                case int:
                    Console.WriteLine($"{(int)obj}는 int 형식입니다.");
                    break;
                case float :
                    Console.WriteLine($"{(float)obj}는 float 형식입니다.");
                    break;
                default :
                    Console.WriteLine($"{obj}는()은 모르는 형식입니다.");
                    break;
            }
        }
    }
}

 

입력받은 문자열은 int 또는 float 형식으로 변환한 후, 변환된 데이터를 object 형식 객체에 박싱해 넣습니다. 그리고 switch 문에서 이 객체 안에 박싱된 데이터의 형식에따라 메시지를 출력합니다.

 

*('형식 패턴'의 경우 C# 9.0 버전이상부터 지원하여 추후 버전 업데이트 후에 결과 값을 다시 테스트 해보겠습니다. ) 

 

케이스 가드

케이스 가드란 switch 문의 case 절의 패턴을 더 구체적으로 만들어주는 추가적인 조건 검사라고 할 수 있습니다. 케이스 가드는 다음 예제처럼 case 절에 뒤에 when 절을 붙여 사용합니다. when 절은 if 문처럼 true/false 로 결과가 나오는 식을 입력받습니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.SwitchExam
{
    class SwitchExam_3
    {
        public void Main()
        {
            string s = Console.ReadLine();
            object obj = null;
            if (int.TryParse(s, out int out_i))
                obj = out_i;
            else if (float.TryParse(s, out float out_f))
                obj = out_f;
            else
                obj = s;

            switch (obj)
            {
                case int:
                    Console.WriteLine($"{(int)obj}는 int 형식입니다.");
                    break;
                case float: // obj가 float 형식이며 0보다 크거나 같은 경우
                    Console.WriteLine($"{(float)obj}는 float 형식입니다.");
                    break;
                case float f when f >= 0:   // obj가 loat 형식이며 0보다 크거나 같은 경우
                    Console.WriteLine($"{f}는 float 형식입니다.");
                    break;
                default:
                    Console.WriteLine($"{obj}는()은 모르는 형식입니다.");
                    break;
            }
        }
    }
}

 

*('형식 패턴'의 경우 C# 9.0 버전이상부터 지원하여 추후 버전 업데이트 후에 결과 값을 다시 테스트 해보겠습니다. ) 

 

 

4. switch 식

식은 결과값을 만들어낼 수 있는 연산자와 연산자의 조합입니다. 즉, 식은 계산을 해서 결과를 내놓습니다.

이에 비해 문은 주어진 일을 할 뿐입니다. 결과를 내든 그렇지 않든 말입니다.

 

그래서 어떤 작업에 분기가 필요할 때는 switch 문을 사용하되, 분기를 거쳐 값을 내야 하는 경우에는 switch 식을 사용하면 더 읽기 좋은 코드를 작성할 수 있습니다. 거기에 break 같은 점프문도 필요 없습니다.

 

먼저 switch 문에서 조건식을 switch 키워드 앞으로 옮깁니다. 그 다음, case 키워드와 : 를 => 로 바꿉니다. break;는 불필요하며, 각 케이스는 콤마(,)로 구분합니다. 마지막으로 default 키워드는 _로 바꾸면 됩니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.SwitchExam
{
    class SwitchExp
    {
        public void Main() {
            Console.Write("점수를 입력하세요 : ");
            int score = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("재수강인가요? (y/n)");
            string line = Console.ReadLine();
            bool repeated = line == "y" ? true : false;

            string grade = (int)(Math.Truncate(score / 10.0) * 10) switch
            {
                90 when repeated == true => "B+",
                90 => "A",
                80 => "B",
                70 => "C",
                60 => "D",
                _ => "F"
            };
            Console.WriteLine($"학점 : {grade}");
        }
    }
}

 

*('재귀 패턴'의 경우 C# 8.0 버전이상부터 지원하여 추후 버전 업데이트 후에 결과 값을 다시 테스트 해보겠습니다. ) 

 

 

 

#2 반복문

반복문은 특정 조건을 만족하는 동안 코드 또는 코드 블록을 반복해서 실행하도록 하는 문장입니다.

C#은 모두 다음 네 가지의 반복문을 제공합니다.

  • while
  • do while
  • for
  • foreach

 

1. while

while (조건식)
	반복_실행할_코드

while 키워드 옆의 조건식은 if 문에서의 조건식과 마찬가지로 논리 형식(bool 형식) 입니다. C#의 while 문은 '조건식이 참인 동안'코드를 반복합니다. 만약 조건식이 false 값을 갖지 못한다면 프로그램은 while 문에서 영원히 헤어나오지 못할 것입니다. 이것을 '무한 반복'이라고 합니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.WhileExam
{
    class WhileExam
    {
        public void Main()
        {
            int i = 10;

            while (i > 0)
            {
                Console.WriteLine($"i : {i--}");
            }
        }
    }
}

 

 

 

2. do while

do while 문은 while 문이 조건식을 평가한 후 그 결과가 참이면 코드를 실행하는 데 반해, do while 문은 조건식을 평가하기 전에 무조건 처음 한 번은 코드를 실행한다는 점이 다릅니다. 또한, do while 문은 끝에 세미콜론(;)을 반드시 붙여줘야 합니다. 그렇지 않으면 컴파일러가 해당구문을 인식하지 못하고 에러 메시지를 출력합니다. 

 

do
{
	반복_실행할_코드_블록	// 이 코드 블록은 최초 한 번은 무조건 실행됩니다.
}
while (조건식);	// do while 문과 while 문의 또 다른 점은바로 ; 입니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.WhileExam
{
    class DoWhileExam
    {
        public void Main() {
        int i = 10;

        do {
                Console.WriteLine("a) i : {0}", i--);
            }
            while (i > 0);
        do {
                Console.WriteLine("b) i : {0}", i--);   // 여기에서 i는 이미 0이지만 이 코드는 한 차례 실행됩니다.
            }
            while (i > 0);
        }
    }
}

 

 

 

3. for

for문도 while문처럼 '조건식이 참인 동안' 코드를 반복 실행하지만, while 문보다 반복을 더 정교하게 제어할 수 있다는 차이가 있습니다.

 

for (초기화식; 조건식; 반복식;)
	반복_실행할_코드;

 

  • 초기화식 : 반복을 실행하기 전에 가장 먼저, 딱 한번만 실행되는 코드입니다. for 반복문에서 사용할 변수 등을 이곳에서 초기화합니다.
  • 조건식 : 반복을 계속 수행할지를 결정하는 식입니다. 이 조건식의 결과가 false가 되면 반복을 중단합니다.
  • 반복식 : 반복이 끝날 때마다 실행됩니다. 주로 여기서 조건식에서 사용하는 변수의 값을 조정합니다. 반복식이 실행된 후에는조건식이 실행되어 반복을 계속 진행할지를 판단합니다. 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.ForExam
{
    class ForExam
    {
        public void Main()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(i);
            }
        }
    }
}

 

 

  1. int 형식 변수 i를 선언하고 0으로 초기화 합니다.
  2. 조건식 i가 5보다 작을지를 평가하여 실행됩니다.
  3. 그 결과가 true면 Console.WriteLine(i)을 실행합니다.
  4. 첫 번째 반복을 수행하고 나면 반복식 i++가 실행되고 뒤이어 또 조건식이 실행됩니다.
  5. 이 조건식이 true인 동안에는 계속해서 Console.WriteLine(i)를 실행합니다.

 

 

4. 중첩 for

for 문은 if 문처럼 2개 정도는 자주 중첩해서 사용하는 흐름 제어문입니다.

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.ForExam
{
    class ForForExam
    {
        public void Main()
        {
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    Console.Write("*");
                }
                Console.WriteLine();
            }
        }
    }
}

 

 

 

5. foreach

foreach 문을 이해하기 위해서는 배열이나 컬렉션의 개념을 이해하고 있어야 합니다.

 

배열 설명을 간단히 하자면, 배열은 다음 그림과 같이 여러개의 데이터를 담을 수 있는 코드 요소이며, 변수 여러 개르르 이어 붙여놓은것과 같다고 할 수 있습니다.

컬렉션도 여러 개의 데이터를 담는 코드 요소라는 점에서 배열과 비슷하지만, 사용하는 방식과 데이터를 저장하고 이에 접근하는 알고리즘이 다릅니다.

 

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
10 20 30 40 50 60 70 80 90 100

 

foreach 문은 이렇듯 배열(또는 컬렉션)을 순회하며 각 데이터 요소에 차례대로 접근 하도록 해줍니다. 편리하게도 배열(또는 컬렉션)의 끝에 도달하면 자동으로 반복이 종료됩니다.

 

foreach(데이터_형식 변수명 in 배열_또는_컬렉션)
	코드_또는_코드_블록

 

이 형식과 같이 foreach 문은 in 키워드와 함께 사용합니다. foreach 문이 한 번 반복을 수행할 때마다 배열(또는 컬렉션)의 요소를 차례대로 순회하면서 in 키워드 앞에 있는 변수에 담아줍니다. 그럼 우리는 그 변수를 이용해 하고 싶은 일을 하면 되는것이죠. 

 

[실습]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsCSharpExam.Ch._05.ForExam
{
    class ForEachExam
    {
        public void Main()
        {
            int[] arr = new int[] { 0, 1, 2, 3, 4 };

            foreach (int a in arr)
            {
                Console.WriteLine(a);
            }
        }
    }
}