본문 바로가기

프로그램&DB/C#

[C# 강좌] C# 프로그래밍 #07 - 흐름제어

2.5 흐름 제어

일반적으로 프로그램은 작성된 코드 순서대로 실행이 된다. 이 실행 순서를 바꾸기 위해 사용되는 방법을 여기서는 설명하도록 하겠다.

 

2.5.1 조건문 if

조건문은 진리값에 따라 코드를 실행해 줄지 말지를 결정해주기 위한 문장이다.

 

1) 단순 조건문

단순 if 문의 경우 다음과 같이 이용될 수 있다.

if (상태)

    수행 코드

 

수행 코드가 여러 줄로 나타날 경우 중괄호를 이용해 묶어 줄 수도 있다.

if (상태) {

    수행 코드1

    수행 코드 2

}

 

위 문장은 단순 조건문의 기본형을 보여주고 있다. 참인 경우만을 가지고 조건을 판단할 때는 위와 같이 이용되고, 거짓인 경우에 다른 코드를 실행해주어야 한다면 다시 else 를 이용하여 조건문을 확장할 수 있다.

 

다음 문장을 보자.

if (비가 온다)  우산을 팔아라.

else 부채를 팔아라.

 

이 문장은 비가 온다라는 명제가 참일 경우 우산을 팔아라.라는 행위를 하고 거짓인 경우 부채를 팔아라.라는 행위를 하라는 의미를 나타낸다. 여기서 중요하게 보아야 할 부분은 if 문 뒤의 소괄호 안에 있는 비가 온다가 참인지 거짓인지에 대한 상태이다.

 

다음 소스를 보자.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.Serialization;

 

namespace Second

{

    class Program

    {

        static void Main(string[] args)

        {

            bool isRaining = true;

 

            if (isRaining)

                Console.WriteLine("우산을 팔아라.");

            else

                Console.WriteLine("부채를 팔아라.");

 

            Console.Read();

        }

    }

}

 

우산을 팔아라.

 

12번째 라인에서는 비가 오는지에 대한 상태를 나타내기 위해 불리언 타입 변수 isRaining를 선언하였다. 14번째 라인은 isRaining의 값이 참인지 거짓인지 유무를 판단해서 참일 경우 15번째 라인을 거짓을 경우 17번째 라인을 출력해주는 구문이다. 결과는 12번째 라인에서 isRaining true로 초기화되어 있기 때문에 우산을 팔아라.는 문장이 출력될 것이다. 만약 isRaining false의 값이 들어가면 부채를 팔아라.는 값이 출력된다.

 

if 문은 상황에 따라 상황에 따라 실행 흐름을 제어해주는 가장 간단한 제어문의 한가지 이다.

 

2) 복합 조건문

여러 개의 값을 가지는 조건에 대해서 조건문이 어떻게 사용되는 지 알아 보리고 하겠다. 나이가 0~2 살까지는 신생아, 2살 이상 8살까지는 영아, 8살 이상 14살까지는 어린이, 14살 이상 20살까지는 청소년이라고 출력하는 프로그램을 생각해보자.

if (나이가 0이상 2보다 작으면)

 신생아 출력

if (나이가 2이상 8보다 작으면)

     영아 출력

if (나이가 8이상 14보다 작으면)

어린이 출력

if (나이가 14이상 20보다 작으면)

청소년 출력

 

위와 같이 각각의 나이의 조건에 따라 if 문을 사용하여 작성할 수 있을 것이다. 그러나 나이라는 공통 요소를 가지고 코드가 구현된다는 점을 생각하면 각각의 독립된 if 문으로 구성되는게 효과적이지 못하며, 복잡한 코드에서 오히려 코드를 읽는데 불편함으로 작용할 수 있다. 다음 소스를 보자

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class Program

    {

        static void Main(string[] args)

        {

            int age = 0;

 

            age = Int32.Parse(Console.ReadLine());

 

            if (age >=0 && age <2)

                Console.WriteLine("신생아");

            else if (age >=2 && age <8)

                Console.WriteLine("영아");

            else if (age >=8 && age <14)

                Console.WriteLine("신생아");

            else if (age >= 14 && age < 20)

                Console.WriteLine("신생아");

            else

                Console.WriteLine("성인");

 

            Console.Read();

        }

    }

 

다음 소스는 else if 를 이용하여 하나의 상태 변수에 대한 여러 가지 상태 값을 처리한 것이다. 공통된 상태 조건인 age에 따라서 상태를 표시해 주는 것이 각각의 if 문을 이용하여 처리한 것보다 효과적임을 알 수 있다. 또한 나열된 조건을 만족하지 않는 경우를 else 문으로 따로 손쉽게 처리해주는 것을 볼 수 있을 것이다.

 

7번째 라인의 Console.ReadLine()은 값을 입력 받기 위한 구문이며, Int32.Parse()는 입력받은 문자 값을 숫자 값으로 변환해 주기 위한 구문이다. 이에 대해서는 자료형 변환을 따로 다루게 될 것이다.

 

3) 중첩 조건문

C#에서 제어문들은 중첩하여 이용할 수 있다. 여기서는 if 문이 중첩되는 예를 간단히 보여주도록 하겠다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class Program

{

    static void Main(string[] args)

    {

        bool isRun = true;

        bool isPrint = true;

 

        if (isRun)

        {

            if (isPrint == true)

            {

                Console.WriteLine("true");

            }

        }

 

        Console.Read();

    }

}

 

8번째 줄의 if 문은 9번재 줄부터 14번째 줄까지 중괄호로 묶어서 isRun true이면 수행되는 구문임을 알 수 있다. 여기에 9~14번째 줄 사이에 또 다시 if 문이 중첩해서 들어가는 것을 볼 수 있다. 이와 같은 경우를 중첩 if 문이라고 부른다. 모든 제어 구문들이 중괄호 사이로 한정된다는 것을 생각하면 쉽게 이해될 것이다.

 

4) 조건 연산자 ?

조건부 연산자는 수행할 코드가 단문일 경우 간단하게 조건문을 이용할 수 있는 방법으로 제공 된다.

(조건) ? 참인 경우 : 거짓인 경우;

 

다음 코드는 isTrue라는 조건의 상태가 참일 때 화면에 true를 거짓일 때 false를 출력해준다.

Console.WriteLine((isTrue) ? "true" : "false");

 

2.5.2 반복문 for, while, do~while, foreach

반복문은 동일한 수행코드를 여러 번 수행해줘야 할 때 유용하게 이용되는 구문이다.

10개의 똑 같은 문자열을 출력해줘야 할 필요가 있을 때 출력문을 10개를 이용하여 출력할 수도 있지만, 반복문을 이용하면 코드가 더 읽기 쉬워진다. 반복의 횟수가 컴파일 타임에 결정되는 경우 출력문을 일일이 타이핑 해주는 것이 수행 속도면에서는 좀더 나을 수 있다. 그러나 일반적으로 반복의 횟수가 상태에 따라 변한다던지, 입력에 따라 변하는 경우 코드를 만드는게 불가능 해진다.

1) for

for(초기값 ; 상태 ; 증가치)

    수행할 코드

 

2) while

While(조건)

    수행할 코드

 

3) do~while

do {

    수행할 코드

} while(조건)

 

4) foreach

배열이나 컬렉션 개체에 대한 반복을 수행하기 위한 구문이다. 컬렉션은 반복기가 구현된 개체로서 그에 대한 설명은 컬렉션을 만들어 보는 장에서 다시 설명하도록 하겠다. 우선 아래 소스를 보자.

1

2

3

4

5

int[] myArray= new int[] { 0, 1, 2, 3, 4, 5};

foreach (int i in myArray)

{

Console.WriteLine(i);

}

 

정수형 배열을 만들고 그 값을 반복하는 구문을 나타내고 있다.

2번째 줄의 foreach문은 정수배열 myArray의 요소들을 i에 담으며 반복을 수행한다.

 

2.5.3 switch

switch 문장의 기본형은 다음과 같다.

switch(상태 변수)

{

    case 상태변수 값 1 :

        수행할 코드

        break;

case 상태변수 값 2 :

        수행할 코드

        break;

case 상태변수 값 3 :

        수행할 코드

        break;

    default :

        수행할 코드

}

break의 의미는 switch 구문을 종료한다는 의미이다.

다음 소스를 보자

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

namespace switch_Sample

{

    class Program

    {

        static void Main(string[] args)

        {

            int index = 0;

 

            index = Int32.Parse(Console.ReadLine());

 

            switch (index)

            {

                case 0 :

                    Console.WriteLine("0이입력되었습니다.");

break;

                case 1:

                    Console.WriteLine("1이입력되었습니다.");

                    break;

                case 3 :

                case 4 :

                case 5 :

                    Console.WriteLine("3, 4, 5중하나의숫자가입력되었습니다.");

break;

                default :

                    Console.WriteLine("6이상의숫자가입력되었습니다.");

 break;

            }

Console.ReadLine();

        }

    }

}

 

 

 

2.5.4 break, continue, goto

 

1) break

switch에서 이미 한번 보여진 바 있다. 제어 구문에 쓰여서 제어구문을 빠져 나오라는 의미로 해석하면 된다. break는 반복문 등에 이용되어진다. 다음 소스를 보자.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

namespace break_Sample

{

    class Program

    {

        static void Main(string[] args)

        {

            bool isExit = false;

 

            for ( ; ; )

            {

                isExit = bool.Parse(Console.ReadLine());

                if (isExit)

                    break;

                else

                    Console.WriteLine("계속");

            }

 

            return;

        }

    }

}

 

13번째 줄은 입력된 isExit 변수가 참일 경우 break문을 이용하고 있다. break 문은 반복되는 for문을 종료하는 역할을 수행한다.

 

2) continue

주로 반복문에서 조건문과 함께 이용되며, 조건부 이하 실행 후 반복이나 실행하지 않고 반복을 제어하는데 이용된다. 다음 소스를 보자. 이 소스에서는 break문과 continue문이 같이 이용되고 있다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

namespace Continue_Sample

{

    class Program

    {

        static void Main(string[] args)

        {

            int index = 0;

 

            for ( ; ; )

            {

                index = Int32.Parse(Console.ReadLine());

 

                if (index == 0)

                {

                    Console.WriteLine(index);

                    continue;

                }

                else if (index == 1)

                    break;

 

                Console.WriteLine("반복");

            }

            return;

        }

    }

}

 

 

3) goto

코드의 수행 순서를 바꾸기 위해 goto 키워드를 이용할 수 있다. goto 키워드에 레이블을 달아서 사용하면 지정된 레이블로 제어의 흐름이 이동하게 된다. 흔히 사용하지 않는 방법이지만, 프로그램을 깔끔하게 만들어 줄 수 있다. break문이 이용된 소스를 goto문을 이용해 바꿔보도록 하겠다. 다음 소스를 보자.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Namespace Goto_Sample

{

    class Program

    {

        static void Main(string[] args)

        {

            bool isExit = false;

 

            for ( ; ; )

            {

                isExit = bool.Parse(Console.ReadLine());

                if (isExit)

                    goto exit;

                else

                    Console.WriteLine("계속");

            }

 

        exit:

            return;

        }

    }

}

필요치 않은 goto 문의 빈번한 이용은 소스코드를 읽기 어렵게 만들 수 있다.


/* 출처 */
inobae의 놀이터
http://blog.naver.com/inobae