Media Log


1. 배열(Array)


배열이란, 동일한 타입의 변수를 모아놓은 데이터 집합이라고 말할 수 있습니다. 예를 들어서, 우리가 각 반 학생들의 한 달 독서량을 변수에 담는다고 가정하면 아래와 같이 변수를 선언해야 합니다.

...
    int reading_1 = 4;
    int reading_2 = 9;
    int reading_3 = 1;
    int reading_4 = 0;
    int reading_5 = 21;
    int reading_6 = 12;
...

보기만 해도 비효율적이고, 만약 반에 학생이 30명 정도가 있다면 비슷한 성격의 변수를 똑같이 30번 선언해야 하며, 전체 학생의 독서량을 사용자에게 제공하려고 변수에 접근하여 값을 얻어올 때도 상당히 불편합니다. 여기서, 배열을 사용하면 이 두 문제를 한 번에 잡을 수 있으며, 익숙해지다 보면 여러 개의 데이터를 다루게 될 때 유용하게 사용할 수 있습니다. 아래는 위 문제를 배열로 구현한 예제입니다.

...
    int[] reading = new int[30]{4, 9, 1, 0, 21, 12, ..., ..., ...}
...

상당히 간편해졌죠? 그리고 배열에 접근할 때는 첨자값(index, 인덱스)으로 접근하는데 여기서 주의하실 점은 첨자값은 항상 0부터 시작한다는 사실을 기억하시고 계셔야 합니다. 아래는 첨자값으로 각 배열 요소에 접근하여 그 값을 출력시키는 예제입니다.

...
    Console.WriteLine("reading[0]={0}", reading[0]); // reading[0]=4
    Console.WriteLine("reading[1]={0}", reading[1]); // reading[1]=9
    Console.WriteLine("reading[2]={0}", reading[2]); // reading[2]=1
...

아까처럼 일일이 변수를 선언하여 접근하는 것과는 다르게 배열의 첨자값을 이용한 접근은 상당히 간단합니다. 이제는 직접 배열을 우리가 선언하고, 배운 사실을 응용하여 다른 프로그램을 만들어보도록 합시다. 아래는 배열의 선언 방법입니다.

자료형[] 배열명 = new 자료형[크기];
크기 6을 가진 int 형식의 배열 student를 선언하려면 아래와 같이 선언하시면 됩니다.
int[] student = new int[6];

student[0] = 4;
student[1] = 9;
student[2] = 1;
..

위와 같이 선언하면 아래와 같이 6개의 공간을 가진 int형 배열 구조를 형성합니다.



이제 배열에 대해 기본적인 사항은 알았으니, 배열을 직접 사용해보도록 합시다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] reading = new int[6] { 4, 9, 1, 0, 21, 12 };

            for (int i = 0; i < reading.Length; i++)
                Console.WriteLine("reading[" + i + "]={0}", reading[i]);
        }
    }
}
결과:
reading[0]=4
reading[1]=9
reading[2]=1
reading[3]=0
reading[4]=21
reading[5]=12
계속하려면 아무 키나 누르십시오 . . .

코드의 12행을 보시면 reading이라는 int형 배열이 선언되었고 6개의 공간을 차지합니다. 그리고 그 공간마다 각각 4, 9, 1, 0, 21, 12란 값으로 초기화되었습니다. 11행을 보시면 for문으로 reading의 길이, 즉 크기만큼 반복하여 코드를 실행합니다. 12행에서는 0부터 5까지 접근하여 그 요소가 가지고 있는 값을 출력합니다.


여기서 9행을 다시 살펴보시면, 배열의 선언과 동시에 초기화를 하고 있는데 이방법 말고도, 배열을 선언하는 방법은 더 있습니다. 배열을 선언하고 그와 동시에 초기화를 한다면 아래와 같은 방법도 가능합니다.

int[] reading = {4, 9, 1, 0, 21, 12};

이렇게 코드를 적어도 에러가 나지 않는 이유는, 초기화 시에 배열 요소의 수로 길이가 지정되기 때문입니다. 그렇기에 크기를 생략해도 정상적으로 컴파일이 가능합니다. 위의 코드는 아래의 코드와 같습니다.

int[] reading = new int[]{4, 9, 1, 0, 21, 12};


2. System.Array


Array 클래스는 배열에 대한 다양한 기능을 제공합니다. 여기서, 클래스가 궁금하신 분들은 다음 강좌에서 'C# 강좌 10편. 클래스(Class)'를 미리 살펴보셔도 괜찮습니다. 기능이 상당히 많아, 그것을 모두 다 강좌에서 설명할 수는 없고 주로 쓰이는 메소드와 속성만 간단히 설명하도록 하겠습니다. 이것 말고도 더 궁금하신 분들은 MSDN를 방문하여 참고하시면 됩니다.


MSDN System.Array 관련 문서: http://msdn.microsoft.com/ko-kr/library/system.array.aspx


분류

이름

기능

속성

Rank

배열의 차원 수를 가져옵니다.

Length 

배열의 길이를 가져옵니다.

메소드

Clear

배열 형식에 따라 정수 형식일 경우 0, 논리 형식일 경우 false, 참조 형식일 경우 null으로 초기화됩니다.

ForEach 

지정한 배열의 각 요소에서 지정한 동작을 수행합니다.

Resize 

배열의 요소 수를 지정된 새로운 크기로 변경합니다.

indexOf 

지정한 개체를 검색하여 1차원 Array 전체에서 처음 검색된 개체의 인덱스를 반환합니다.


위의 표는 주로 사용되는 속성과 메소드를 정리한 것입니다. Rank 부터 시작하여 직접 사용하여 어떠한 기능을 하는지 알아보도록 하겠습니다. 아래 예제는 Rank, Length, Clear, ForEach, Resize, indexOf가 사용된 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] reading = new int[] { 4, 9, 1, 0, 21, 12 };

            Console.WriteLine("속성: Rank={0}, Length={1}", reading.Rank, reading.Length);
            // reading의 차원 수와 길이를 반환함

            Console.Write("Clear 메소드: ");
            Array.Clear(reading, 0, 5); // 배열 요소를 0부터 시작하여 5개의 요소를 초기화 시킴
                                        // Array.Clear(요소를 지울 배열, 시작 인덱스, 지울 요소수);
            Array.ForEach(reading, new Action(ShowValue));
            // 해당 배열의 각 요소를 가지고 동작(ShowValue)를 수행함
            // Array.ForEach<데이터타입>(동작을 수행할 배열, new Action<데이터타입>(액션);
            Console.WriteLine();

            Console.Write("Resize 메소드: ");
            Array.Resize(ref reading, reading.Length + 3);
            // reading 배열의 길이를 3만큼 늘림, Array.Resize(배열의 주소값, 새 배열의 크기);
            Array.ForEach(reading, new Action(ShowValue));
            Console.WriteLine();

            Console.WriteLine("indexOf 메소드: {0}", Array.IndexOf(reading, 12));
            // 배열에서 12란 값을 가지고 있는 요소의 인덱스를 반환함
            // Array.IndexOf(배열, 찾고자 하는 값);
        }

        static void ShowValue(int value) // 동작, value를 받아 그 value를 출력시킴
        {
            Console.Write("{0} ", value);
        }
    }
}
결과:
속성: Rank=1, Length=6
Clear 메소드: 0 0 0 0 0 12
Resize 메소드: 0 0 0 0 0 12 0 0 0
indexOf 메소드: 5
계속하려면 아무 키나 누르십시오 . . .

결과를 보아 상당히 유용함을 알 수 있습니다. 코드에 주석을 달아놓았긴 했으나, 각 메소드의 사용 형식을 더 자세히 알고 싶으시다면 MSDN를 방문하여 참고하시기 바랍니다. 

3. 다차원 배열(Multidimensional array)

다차원 배열이란, 말 그대로 여러 개의 차원을 다루는 배열입니다. 우리가 지금까지 만나봤던 배열들은, 모두 가로로만 이루어진 1차원 배열이었습니다. 이번엔 주로 쓰이는 2차원 배열에 대해 알아보도록 하겠는데, 2차원 배열은 1차원 배열과는 달리 가로와 세로를 가지는 평면 구조의 사각형으로 이루어져 있습니다. 


만약에 student란 2차원 배열이 있고 열이 6, 행이 3인 배열이 있다고 합시다. 그렇게 되면 위와 같은 구조를 형성합니다. 1차원 배열의 요소에 접근하는 방법과 2차원 배열의 요소에 접근하는 방법은 비슷합니다. 3열 2행에 있는 값을 가져오고 싶다면, student[2][1]라고 하시면 되겠죠. 아래는 2차원 배열을 선언하는 형식입니다.

자료형[,] 배열명 = new 자료형[행, 열];

이제 2차원 배열을 직접 다루어 컴파일을 해보도록 하겠습니다. 아래 예제는 2차원 배열을 다루는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] reading = new int[3, 6] { { 4, 9, 1, 0, 21, 12 }, { 1, 4, 6, 0, 9, 5 }, { 4, 4, 2, 4, 0, 0 } };

            for (int i = 0; i < reading.GetLength(0); i++)
                for (int j = 0; j < reading.GetLength(1); j++)
                    Console.WriteLine("reading[" + i + ", " + j + "] = {0}", reading[i, j]);
        }
    }
}
결과:

reading[0, 0] = 4

reading[0, 1] = 9

reading[0, 2] = 1

reading[0, 3] = 0

...

reading[2, 4] = 0

reading[2, 5] = 0

계속하려면 아무 키나 누르십시오 . . .


코드의 9행을 보시면 reading이라는 2차원 배열이 선언됨과 동시에 초기화를 하고 있고, 그다음에 for문의 중첩이 등장합니다. for문의 조건식에 쓰인 GetLength라는 메소드는 각 차원의 요소 수를 반환하는 메소드입니다. 즉 GetLength(0)은 3이되고, GetLength(1)은 6이 됩니다. 여기선 0부터 차원이 시작합니다. 0은 1차원, 1은 2차원을 의미합니다. 그리고 반복하면서 각 요소의 값을 출력시키고 프로그램이 종료됩니다.


  문자열 사이에 있는 + 연산자는 무엇인가요?


지금까지 배운 바로는 + 연산자는 산술 연산자라고 볼 수 있는데, 피연산자가 정수나 실수가 아닌 문자열이 등장했습니다. 우리가 나중에 배우게 될 개념이지만, 연산자 오버로딩(Operator Overloading)을 통해서 문자열 형식에 대해서도 연산이 미리 정의가 되어 있습니다.


예) "안녕, 내 이름은 " + name + "이야." -----> "안녕, 내 이름은 홍길동이야."


위와 같은 방법은 상당히 작성하기 쉽고, 보기에도 직관적입니다. + 연산자의 피연산자 중 하나가 문자열이고, 다른 하나가 숫자 형식인 경우에도 미리 정의가 되어 있기 때문에 연결할 수 있습니다. 


2차원 배열 말고도, 3차원, 4차원, 5차원.. 배열이 있으나 많이 쓰이지는 않습니다. 복잡하기 때문이죠. 만약에 3차원 배열을 선언하고 싶으시다면 아래와 같은 방법으로 선언하시면 됩니다.

자료형[,,] 배열명 = new 자료형[높이, 세로, 가로];

배열에 대한 설명은 여기서 마치도록 하겠습니다. 수고하셨습니다.


다음 강좌에서는 클래스(Class)에 대해 알아보도록 하겠습니다.

  1. need at 2012.09.16 14:05 신고 [edit/del]

    vb쪽도 써주시면 감사하겠습니다.
    강좌보고 배우고 있는데 감사합니다

    Reply
  2. C# at 2012.10.14 16:53 신고 [edit/del]

    강의 정말 잘보고 있어요
    정말 감사합니다

    Reply
  3. C# at 2012.10.14 16:53 신고 [edit/del]

    혹시 질문같은거 있으면 질문해도 될까요?

    Reply
  4. 김승현 at 2012.10.20 13:13 신고 [edit/del]

    감사합니다~

    Reply
  5. 새싹 at 2012.11.21 02:15 신고 [edit/del]

    엑시노아님 포스트 보고 프로그래밍 공부 하고 있습니다 :D
    감사합니다.

    질문 하나만 드릴게요.
    다차원 이상의 배열에서 array클래스의 속성들은 가볍게 적용이 되는데
    메소드는 어떻게 이용하나요 ''?
    'int[*,*]에서 int[]로 변환할 수 없습니다'란 경고창이 떠서 수정해보고 있는데
    잘 안돼요 _ _...

    Reply
  6. 감사합니다 at 2013.02.19 13:45 신고 [edit/del]

    다차원배열에서 3행 6열인것 같은데 오타가 나신 것 같습니다....

    헷갈릴수도 있으니 수정좀 부탁드릴께요 ㅎㅎ

    좋은 강좌 감사드립니다~

    Reply
    • 감사합니다 at 2013.02.19 13:49 신고 [edit/del]

      아 .. 저와는 다른 방식으로 행렬을 짜신거군요 ㅠㅠ

      가로의 수가 열이 되는건가요.. 순간 헷갈렸습니다 ㅎㅎ

    • BlogIcon EXYNOA at 2013.02.19 14:02 신고 [edit/del]

      3행 6열이 맞는것 같습니다. 수정했습니다. 감사합니다!

    • 고훈 at 2016.09.17 10:51 신고 [edit/del]

      좋은 글 늘 감사합니다..

      위 예제에서 2행 3열 인 '6'값을 가져오려면 이거 student[1][2] 아닌가요?

      student[2][1] 이면 '4' 값을 가죠오는거죠?

  7. ZiNee at 2013.10.14 01:02 신고 [edit/del]

    다차원 배열이 C와는 차이가 좀 있네요. 소스를 따라 코딩해보면서 강의 보고 있습니다.
    좋은 강좌 올려주셔서 감사합니다.

    Reply
  8. Yong at 2013.12.02 17:07 신고 [edit/del]

    질문이 한가지 있는데요
    C#에서는 포인터와 같은 개념이 없다고 들었습니다. 포인터는 있지만 실질적으로 잘 사용하지않는다는 이야기를 많이 들었고.. C#.net이 메모리의 크기를 자동으로 지정해준다는 이야기를 얼핏 들은 적이있습니다. 배열을 통해 유동하는 크기의 배열을 만들려면 어떻게 해야하나요??

    Reply
    • BlogIcon EXYNOA at 2013.12.02 17:39 신고 [edit/del]

      네, 그렇습니다. 아마 C#에도 포인터를 사용할 수 있지만 unsafe 키워드를 같이 사용하셔야 하는 것으로 알고 있습니다. 말씀하신 그대로, 메모리의 크기를 자동으로 지정해주며 동적 배열을 만드시려면 new 키워드를 통해 작성해주시면 됩니다.

      string[] str = new string[i];

      위와 같은 식으로 말이죠. 아니면 '유동'이 크기가 정해져 있지 않고 줄였다가 늘였다가 할 수 있는 것이라면 컬렉션을 쓰시면 될 것 같습니다. List나 ArrayList같은 자료구조를 한번 알아보시면 좋을 것 같습니다. ^-^*

  9. studyingQ at 2014.06.17 09:39 신고 [edit/del]

    안녕하세요. C#을 공부하고 있습니다. 궁금한 점이 있어 문의 드립니다.

    1) int[] reading = {4, 9, 1, 0, 21, 12}; 문장과
    2) int[] reading = new int[]{4, 9, 1, 0, 21, 12}; 이 같다고 표현하셨는데

    C++의 경우
    동적할당을 위해서는 포인터를 이용한 방식
    int* pInt= new int[]; 만 가능한 것으로 알고 있습니다.

    1) 방식과 같이 C++에서 int a[]={1,3,5}; 배열을 선언하면 동적할당이 아닌 스텍에
    할당되며 2)와 같은 방식은 선언 자체가 불가능한 것으로 알고 있습니다.

    C#에서 위와 같은 두 개의 선언이 동일한 이유(1번 형식이 스텍이 아닌 동적 할당이 이루어 지는 이유)와 제가 알고 있는 내용 중 잘못된 부분이 있다면 설명 부탁드립니다.

    감사합니다.




    Reply
    • BlogIcon EXYNOA at 2014.06.17 23:38 신고 [edit/del]

      C++와 C#를 동일시 하시면 안됩니다. 말 그대로, C#에서의 1차원 배열 초기화 방법은 대표적으로 세가지가 존재하며 그 중 두개가 1)과 2)인 것입니다. 만약 아래와 같은 예제가 있다고 생각해보세요.

      int[] reading = new int[]{4, 9, 1, 0, 21, 12};

      그런데 여기서 MSDN에 의하면 위와 같이 이니셜라이저, 즉 초기값이 주어진 경우에는 new 연산자를 생략할 수 있다고 합니다. 그렇다면, 아래와 같은 형태도 위와 같은 형태와 동일한 형태를 가집니다.

      int[] reading = {4, 9, 1, 0, 21, 12};

      또한, 1)과 2)는 정적 할당이며, 단지 크기가 명시되지 않고 컴파일러가 주어진 이니셜라이저에 따라 배열의 크기를 정해주는 것입니다. 궁금한 내용이 더 있으시다면 네이트온 혹은 메일로 남겨주시면 감사하겠습니다 ^ㅡ^*

  10. studyingQ at 2014.06.18 10:59 신고 [edit/del]

    답변 감사드립니다. ^--^

    약간의 키워드에 대한 착각이 있었습니다.
    new 키워드의 경우
    new 연산자, new 한정자, new 제약 조건의 다양한 기능을 가지고 있네요...

    C++과 착각하여 new 연산자를 동적할당이라고 착각했습니다.
    음.. 배열같은 경우에도 내부적으로 resize가 가능하고....
    그렇다면 C#에서는 동적할당이 큰 의미가 없는것인가요? 메모리 관리는 가비지컬렉터에 의해 수행되며.....

    가능하시다면 답변 부탁드립니다. ^^

    Reply
    • BlogIcon EXYNOA at 2014.06.21 19:11 신고 [edit/del]

      C#에서도 동적 메모리 할당이 물론 존재합니다. 이것도 이것대로 C#에선 나름대로의 의미를 지니고 있으며, C#에서도 동적 할당시 new 연산자가 사용되는건 마찬가지 입니다. 댓글로 의문을 풀어들이기에는 얘기가 길어질 것 같은 조짐이 보이네요..

  11. BlogIcon Siddhartha at 2014.08.09 15:59 신고 [edit/del]

    오늘도 정말 재밌게 잘 봤습니다, 감사합니다 !

    Reply
  12. ㅇㅎ at 2015.01.17 00:30 신고 [edit/del]

    [+ i +]는 무엇인가요?

    Reply
    • 안나 at 2015.01.19 14:54 신고 [edit/del]

      i는 reading[0], reading[1], reading[2] 할 때 0, 1, 2에 해당하는데
      따옴표를 사용해줘야 for문의 i값이 들어갑니다!
      따옴표를 사용하지 않으면 단순히 [i]로 찍혀나오며
      +는 i와 "를 함께 쓸 수 있게 해주는 역할로 사용 되어요
      저도 초보라 이 정도 뿐이 설명을 못드리겠네요 ㅠㅠ 죄송합니다

    • BlogIcon EXYNOA at 2017.11.26 17:00 신고 [edit/del]

      해당 질문에 관한 내용을 본문에 추가했습니다.

  13. jacoby at 2015.02.23 14:08 신고 [edit/del]

    안녕하세요 질문이 있습니다 엑시노아님 .

    "AB, AB",
    "Ab, ab",
    ",aB, ab",

    이런식으로
    (,) 쉼표를 기준으로 앞과 뒤의 단어를
    대문자 기준으로 정렬 시키고자 하는데요
    몇일 고민하다가 글을 올려 봅니다. ㅜㅜ

    Reply
  14. ThankYou at 2015.06.21 17:49 신고 [edit/del]

    너무 너무 유용한 자료입니다. 이제 막 프로그래밍을 시작했는데 가장 쉽고 알기 쉽게 알려주시네요ㅠㅠbb
    감사합니다!

    Reply
  15. 광영 at 2017.04.18 11:05 신고 [edit/del]

    new 는 깔록처럼 0으로 초기화하는군요!

    Reply
  16. 노경훈 at 2017.06.20 12:00 신고 [edit/del]

    Array.ForEach<int>(reading, new Action<int> (ShowValue));

    강의 정말 유용하게 잘 보고 있습니다.
    그런데 위의 문장을 입력하면

    The name 'ShowValue' does not exist in the current context. 라고 나오면서 진행이 안되네요
    답변 부탁드립니다.

    Reply
    • bit at 2017.06.22 14:52 신고 [edit/del]

      ShowValue 는 스크립트 하단에 보시면
      메소드 구현 되있습니다

      경훈님 코드에 ShowValue 메소드가 구현되어있는지 확인해보세요
      혹시 스펠링도 확인해보시고...

submit


1. 메소드(Method)


이번 강좌에서는 메소드가 무엇인지, 메소드가 어떠한 기능을 하는지, 또 어떻게 쓰이는지 알아보도록 하겠습니다. C#에서의 메소드(Method)는, C언어와 C++의 함수(Function)와 비슷한 기능을 합니다. 메소드를 간단히 나타내자면, 이어지는 코드들을 묶어놓은 코드 블록입니다. 예를 들어서, 아래는 제곱 후 결과물을 출력하는 기능을 가진 메소드입니다.

...
    static void square(int a) {
        Console.WriteLine("{0}*{1}={2}", a, a, a*a);
    }
...

위 코드는, square라는 녀석에게 값을 넘겨주고, 임시로 a라는 변수에 값을 기억시킵니다. 그리고 이 a 변수를 가지고 제곱하여 출력하는 코드입니다. 대충 메소드를 어떻게 정의하는지 보이시나요? 아래는 C#에서 메소드를 정의하는 방법입니다.

[접근 지정자] 반환형식 메소드명(매개변수 목록) {
    // 실행될 코드
}

여기서 접근 지정자에는, private, public, protected 등이 있습니다. 말 그대로 접근 가능한 범위를 지정할 수 있으며, 접근 지정자에 대한 설명은 나중에 더 자세히 다룰 예정입니다. 반환 형식은 메소드의 결과에 따라 다릅니다. 반환되는 데이터의 형식이 int형이라면, int를 써야하며 double형이라면 double을 반환형식에다 적어주어야 합니다. 만약에 반환되는 값이 없을 경우에는 void를 적으시면 됩니다. 그리고 매개변수 목록은 메소드 호출 시 값을 넘길 수 있도록 하는 '매개변수'가 1개 이상 등장합니다.


아래의 예제는 반환형식의 이해를 돕기위한 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("{0}", Division(40, 10));
        }

        static int Division(int a, int b)
        {
            return a / b;
        }
    }
}
결과:
4
계속하려면 아무 키나 누르십시오 . . .

우선은 예제의 9행을 봅시다. 이상한 게 있다면 인자 부분에 변수나 어느 값이 아닌 Division라는 메소드가 등장했습니다. 15행의 Division라는 메소드를 살펴봅시다. 이 메소드는 두 정수를 매개변수로 받습니다. 우리는 40과 10이란 값을 각각 넘겼으므로, 40이란 값은 매개변수 a에 저장되고, 10이란 값은 매개변수 b에 저장됩니다. 그러곤 메소드가 이 a, b를 이용하여 결과를 만들어 호출부로 반환(return)합니다.

return 부분을 보자면, a가 40, b가 10이므로 결과는 4가 됩니다. 그러곤 return를 만나 4라는 값을 호출된 부분으로 반환합니다. 즉, 이 메소드를 불러냈던 곳으로 결과를 다시 보낸다는 말과 같습니다. 결과가 4이므로 Division(40, 10)은 4라는 값을 가지게 됩니다. 그래서 결과처럼 4라는 결과가 출력될 수 있었던 거죠. 그리고 한가지 주의할점이 있는데, return 키워드는 맨 마지막에서만 등장하는 것이 아니라 코드의 중간에서도 등장할 수도 있습니다. 또한, return 키워드를 만나게 되면 메소드에서 빠져나온다는 사실을 알고 계셔야 합니다. 

2. Call by value vs Call by reference

Call by value와 Call by reference가 무엇인지 설명하기전에, 예제를 한번 짚고 넘어갑시다. 아래 예제에서는 두 매개변수의 값을 교환하는 Swap란 함수가 등장합니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 40;
            int b = 10;

            Console.WriteLine("Swap before: a={0}, b={1}", a, b);

            Swap(a, b);

            Console.WriteLine("Swap after: a={0}, b={1}", a, b);
        }

        static void Swap(int a, int b)
        {
            int temp = b;
            b = a;
            a = temp;
        }
    }
}
결과:
Swap before: a=40, b=10
Swap after: a=40, b=10
계속하려면 아무 키나 누르십시오 . . .

먼저, 코드를 보자면 19행에서 Swap란 함수가 등장합니다. Swap 함수의 내용을 보자면 값을 임시로 담아둘 temp란 변수를 선언하고 temp란 변수의 값을 b의 값으로 초기화시킵니다. 그러고는 b에 a의 값을 담습니다. 그리고 a에는 temp(원래 b의 값)을 담습니다. 즉, Swap 함수는 a와 b의 값을 서로 바꿔버리는 기능을 수행합니다. 여기서 이렇게 매개변수를 변수의 값으로 가져온 경우를 Call by value(복사에 의한 함수 호출)이라고 부릅니다. 

다시 9행으로 돌아가, 정수형 변수 a와 b가 선언되었으며 그와 동시에 40과 10으로 각각 초기화되었습니다. 그러곤 Swap 함수가 실행되기 전의 a, b의 값을 출력한 뒤에 Swap 함수가 실행되고 다시 한번 a, b의 값을 출력합니다. 그러나 Swap 함수가 실행됨에도 불구하고 a와 b의 값은 바뀌지 않습니다. 왜 값이 바뀌지 않았던 걸까요?

우리가 메소드로부터 변수를 넘겨줄 때부터, 매개변수 a와 b이 변수 a와 b를 가르키는 게 아니고, 그저 변수 a와 b의 값을, 매개변수 a와 b로 복사하는 것 뿐입니다. 한마디로 말하자면, 매개변수 a와 b, 변수 a와 b는 서로 별개이며, 다른 메모리 공간을 사용합니다. 그저 매개변수 a와 b의 값이 서로 바뀌었을 뿐, 변수 a와 b의 값은 그대로인 셈이죠. 그렇다면 변수 a와 b의 값을 바꾸도록 하려면 어떻게 해야할까요? 바로 Call by reference(참조에 의한 호출)로 넘긴다면 가능합니다. Call by reference는 Call by value와는 달리, 변수의 주소 값을 매개변수로 보냅니다. 직접 원래의 변수를 참조하는 방법입니다.

한번 위의 예제를 Call by reference로 넘겨보도록 하겠습니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 40;
            int b = 10;

            Console.WriteLine("Swap before: a={0}, b={1}", a, b);

            Swap(ref a, ref b);

            Console.WriteLine("Swap after: a={0}, b={1}", a, b);
        }

        static void Swap(ref int a, ref int b)
        {
            int temp = b;
            b = a;
            a = temp;
        }
    }
}
결과:
Swap before: a=40, b=10
Swap after: a=10, b=40
계속하려면 아무 키나 누르십시오 . . .

아까의 예제와 비교해보면 ref라는 새로운 녀석이 등장합니다. ref 키워드는 매개변수를 참조형식으로 사용할 때 사용되는 키워드입니다. 메소드의 선언, 호출 부분에 ref 키워드를 달아주면 그게 곧 Call by reference로 넘겨주는 방법입니다. 결과를 살펴보면 a와 b의 값이 서로 바뀐 것을 확인하실 수 있습니다. 즉, 원본의 데이터의 값이 바뀐 것을 알 수 있습니다. 

3. 메소드 오버로딩(Method Overloading)

우리가 알고 있는 그대로 C언어에서는 오버로딩이 불가능했습니다. 메소드명을 중복하여 다르게 구현하는 것이 불가능했죠. 그런데 C#에선 메소드 오버로딩을 지원합니다. 같은 메소드명에 인자만 다르게 하여 매개변수의 데이터 형식, 수에 따라 그에 맞는 코드를 실행할 수 있게 됐습니다. 아래는 오버로딩의 예입니다.
..
    static int Add(int a, int b) {
        Console.WriteLine("두 int형 끼리의 덧셈");
        return a + b;
}

    static int Add(double a, double b) {
        Console.WriteLine("두 double형 끼리의 덧셈");
        return a + b;
    }

    static int Add(int a, int b, int c) {
        Console.WriteLine("세 int형 끼리의 덧셈");
        return a + b + c;
    }
..
위 예제를 보시면 같은 메소드명인데도 불구하고 여러 번 등장합니다. 이렇게 똑같은 메소드명인데도 불구하고 매개변수에 따라 호출되는 메소드가 다릅니다. 아래는 오버로딩의 예입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("{0}", Add(50, 10));
            Console.WriteLine("{0}", Add(544.2, 63.2));
            Console.WriteLine("{0}", Add(4, 7, 9));
        }

        static int Add(int a, int b)
        {
            Console.WriteLine("두 int형 끼리의 덧셈");
            return a + b;
        }

        static double Add(double a, double b)
        {
            Console.WriteLine("두 double형 끼리의 덧셈");
            return a + b;
        }

        static int Add(int a, int b, int c)
        {
            Console.WriteLine("세 int형 끼리의 덧셈");
            return a + b + c;
        }
    }
}
결과:
두 int형 끼리의 덧셈
60
두 double형 끼리의 덧셈
607.4
세 int형 끼리의 덧셈
20
계속하려면 아무 키나 누르십시오 . . .

코드의 9행을 보시면, Add 메소드로 세 번이나 다른 형태의 값들을 전달하였음에도 불구하고 결과를 보시면 제대로 출력됨을 확인할 수 있습니다. 14행에 있는 Add 메소드는 두 정수가 넘어올 때 호출되고, 20행에 있는 Add 메소드는 두 실수가 넘어올 때 호출되며, 26행에 있는 Add 메소드는 세 정수가 넘어올 때 호출됩니다. 이처럼, 매개변수의 형식과 수에 따라 호출되는 메소드가 다름을 알 수 있습니다. 유용하죠?

4-1. ref

우리가 방금 넘어왔던 Call by reference 예제에서 ref 키워드를 한번 만났었죠? ref 키워드의 역할은 대충 알고 계시겠지만, 다시 한번 짚고 넘어가도록 하겠습니다. ref 키워드를 사용하면 변수의 값을 그대로 전달하는 게 아닌, 변수의 메모리 주소를 전달한다고 기억합시다. 아래는 ref 키워드가 사용된 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 40;

            Add(ref a, 100);
            Console.WriteLine("a={0}", a);

            Add(ref a, 200);
            Console.WriteLine("a={0}", a);

            Add(ref a, 300);
            Console.WriteLine("a={0}", a);
        }

        static void Add(ref int a, int b)
        {
            a += b; // a = a + b;
        }
    }
}
결과:
a=140
a=340
a=640
계속하려면 아무 키나 누르십시오 . . .

코드를 보시면, ref 키워드가 메소드를 호출할때도 쓰였고 매개변수에서도 사용됬습니다. Add 메소드의 매개변수에 변수 a의 주소값을 넘겨주는 셈이죠. 실제 a의 주소를 안 Add 메소드는 a에다 매개변수 b의 값을 a에다 더합니다. 결과를 출력해봤더니, 정상적으로 덧셈이 진행됨을 알 수 있습니다. ref 매개변수를 사용하려면 메소드를 호출할때나, 메소드를 정의할때도 ref 키워드를 명시적으로 사용해주어야 합니다.

4-2. out

out 키워드는 ref 키워드와 비슷하게 인수를 참조로 전달할때 사용됩니다. 그러나 차이점이 존재합니다. out 키워드를 사용하면 변수를 전달하기전 초기화해야하는 ref 키워드와는 달리 초기화 하지 않고도 전달이 가능합니다. 아래는 out 키워드의 사용 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a;

            Add(out a);
            Console.WriteLine("a={0}", a);
        }

        static void Add(out int a)
        {
            a = 100;
        }
    }
}
결과:
a=100
계속하려면 아무 키나 누르십시오 . . .

12행을 보시면 정수형 변수 a가 등장하나 초기화는 되지 않은것을 확인할 수 있습니다. 14행에서는 Add 메소드가 등장하고 매개변수로 변수 a의 주소값을 넘깁니다. 18행에서의 Add 메소드에서, 이 a의 주소값을 가지고 a에 접근하게 됩니다. a에 100이란 값을 대입합니다. 그러면 a가 가지고 있는 값은 100이 되죠. 메소드를 빠져나와 a의 결과를 출력해보면 성공적으로 a의 값이 100이 됨을 알 수 있습니다.

4-3. params

우리가 만약, 길이에 제한받지 않고 수를 넘겨주어 그 수의 총 합을 구하고 싶을때는 어떻게 하면 될까요? 바로 params 키워드를 사용하면 쉽게 구할 수 있습니다. params 키워드의 기능은 메소드에 여러개의 값을 전달할 수 있도록 도와줍니다. 아래는 params 키워드가 사용된 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("sum={0}", total(20, 10, 40, 4, 7, 6, 44, 55, 2));
            Console.WriteLine("sum={0}", total(30, 4, 5));
        }

        static int total(params int[] list)
        {
            int sum = 0;

            for (int i = 0; i < list.Length; i++)
                sum += list[i];

            return sum;
        }
    }
}
12~13행의 코드를 보시면 길이에 제한 없이, 값을 total 메소드로 넘겨줍니다. 그러면, 16행의 total 메소드를 살펴보도록 합시다. 매개변수 부분에 params 키워드가 사용됬고 int형 뒤에 []가 붙었습니다. 여기서 params 키워드 말고도 배열이란 개념이 사용되었으나, 우리는 아직 배열을 배우지 않았으므로 간단히 이해하고 넘어가도록 하겠습니다. 배열(Array)은 변수들이 줄지어 서있는 것과 같다고 생각하시면 됩니다. 변수들의 모임이죠. 즉, int[]는 정수형 배열을 의미합니다. 우리가 total 메소드로 20, 10, 40, 4, 7, 6, 44, 55, 2를 넘김으로써 list에는,
list = {20, 10, 40, 4, 7, 6, 44, 55, 2}
위와 같이 저장되게 됩니다. 그러고 이 list를 가지고 하나하나 접근하여 sum이란 변수에 더하고 반복문을 빠져나와 sum의 값을 반환(return)합니다. for문을 잠깐 살펴보자면, list.Length는 배열 list의 길이를 구해주는 역할을 합니다. 그리고 for문 내를 보면 list[i]처럼 배열에 들어있는 각 요소에 접근할 경우에는 첨자값(index, 인덱스)값으로 접근합니다. 아직은 배열을 배우지 않아 이해가 안되실지도 모르겠지만, 여기서 중요한건 params 키워드를 사용하여 매개변수의 길이를 유연하게 만들수 있음을 아셔야 합니다. 

오늘의 강좌는 여기서 마치도록 하겠습니다. 수고하셨습니다.

다음 강좌에서는 배열(Array)에 대해 설명합니다.


  1. 김승현 at 2012.10.20 00:39 신고 [edit/del]

    감사합니다~

    Reply
  2. 데오늬 at 2012.11.30 17:17 신고 [edit/del]

    좋은 강좌 잘보고 갑니다~

    Reply
  3. 황순표 at 2012.12.06 10:51 신고 [edit/del]

    유용하게 잘 보고 있습니다. 쉽지 않은 작업일텐데..감사합니다.

    Reply
  4. C#고고 at 2013.03.21 14:49 신고 [edit/del]

    처리되지 않은 형식이라면서 에러가 나네요 ㅠ.ㅠ 어떡해 해야되는건지;;;
    params 문에서 그러네요 ㅠ.ㅠ

    Reply
  5. 외톨이 혁명전쟁 at 2013.03.31 09:09 신고 [edit/del]

    근데 Division메소드는 오버로딩이 안됩니다. 왜 그런가요? 그리고 오버로딩이 가능한 메소드는 또 무엇이 있는지 궁금합니다.

    Reply
    • BlogIcon EXYNOA at 2013.03.31 12:30 신고 [edit/del]

      Division 메서드도 오버로딩 됩니다. 오버로딩 되고 안되는 메서드는 따로 존재하지 않습니다. 어떻게 작성하셨는지 보여주세요.

  6. smfinety at 2013.06.12 17:08 신고 [edit/del]

    감사...잘 배우고 있습니다

    Reply
  7. ZiNee at 2013.10.14 00:22 신고 [edit/del]

    params 키워드는 참으로 유용하네요. 강좌 감사합니다.

    Reply
  8. 이시도르 at 2015.01.28 18:18 신고 [edit/del]

    소중한 강의 감사합니다.
    문제는 프로그래밍 초짜인 제가 메모리 주소개념에서 좀 헷갈리네요 ㅎㅎ

    Reply
    • BlogIcon EXYNOA at 2015.11.13 15:55 신고 [edit/del]

      답글을 늦게 달아드리게 되어서 죄송하다고 말씀드리고 싶습니다. 메모리 주소 개념 중 어느 부분이 헷갈리시는지 말씀해주시면 그 부분을 중심으로 더 자세히 설명하는 방향으로 나가겠습니다.

  9. 중요중요 at 2015.10.14 20:35 신고 [edit/del]

    이부분은 중요한 것들이 많이 나오네요.
    외울 때까지 복습해야겠어요!

    Reply
  10. 광영 at 2017.04.18 10:43 신고 [edit/del]

    ref키워드와 out 키워드가 좀 까다롭네요. ref 자체는 *와 &를 단순화 시켜 놓은 좋은 아이디어라고 생각하고 이해할 수 있었는데, out 은 대체 왜..... 시험삼아서 int a; function(ref a); static void fun(ref int a){a=100;} 하니까 에러 토해내더군요. 그러면서 할당되지 않은 변수를 쓰려 하지 마라 라고 하는데, 이게 그렇다면 값을 넣을 때 비로소 할당된다 라고 이해하면 되는 걸까요? 파이썬마냥 모든걸 다 객체로 봐서 쓸 때 할당하려고 하는 것인지 참 헷갈리네요.

    Reply
  11. at 2017.11.08 17:01 신고 [edit/del]

    강의 잘 보고 있습니다..
    return의 개념에 대해 궁금해서 댓글 남깁니다..
    처음 메소드를 설명해주실때 void를 없애서 return값을 설정해서
    Division을 호출했던곳으로 돌아간거까지는 이해를 했습니다.
    다음 Call by value vs Call by reference 설명 부분에서는
    ref의 역할을 설명이 중점이 되어 있는데 이 부분에서
    Swap 메서드에는 void로 리턴값이 없음에도 불구하고
    a,b가 스왑된 값이 main함수의 Swap 호출부분에 적용이 된걸 볼수있습니다. 그 아래부분들도 다 비슷한 케이스구요..
    return값이 없어도 값이 전달되었다는 의미인거 같은데
    어떻게 이해하는게 좋을지 댓글 부탁드립니다..

    Reply
    • BlogIcon EXYNOA at 2017.11.10 05:07 신고 [edit/del]

      변수마다 자신만의 메모리 공간을 가지고 있습니다. 값에 의한 호출(call by value)의 경우에는 메소드로 값을 넘기면, 그 값이 메소드의 매개변수에 복사되는 것입니다.

      복사된 이후론, main에 있는 지역변수 a, b와 Add 메소드의 매개변수 a, b는 별개의 메모리 공간을 사용합니다. 그렇다면, 함수 내에서 매개변수를 가지고 아무리 값을 수정해도 원래 변수에는 영향을 미치지 않습니다.

      반면에, 참조에 의한 호출(call by reference)와 같은 경우에는 값에 의한 호출과는 달리 main에 있는 지역변수 a, b를 매개변수 a, b를 통해 간접적으로 참조합니다. 이렇게 되면 복사본이 아닌 원본을 수정하는 것이므로, 결과에 영향을 미치게 되는 것입니다.

submit


1. 무한 루프(infinite loop)


전 강좌에서 말했었듯이, 무한 루프란 종료문을 만나지 못하고 끝없이 동작하는 것을 의미합니다. 개발자의 예상치 못한 실수로 중간에 무한 루프가 발생하면, 반복문 내의 코드가 계속해서 실행되므로 자칫하면 비정상적으로 프로그램이 종료될 수 있습니다. 그런데, 이 무한 루프가 단점만 있는 것이 아니라 장점도 존재합니다. 예를 들어, 사용자에게 계속 입력받으며 루프를 돌다가, 특정 문자가 입력되면 루프를 종료하는 것처럼 계속 반복되다가 특정한 조건을 만족하면 빠져나오게 할 수도 있습니다.


아래는 무한 루프의 예입니다.

..
while (true) { // 항상 참이므로 무한 루프에 빠진다.
// 실행될 코드
}
..

위의 예를 보시면, 조건식에 참(true)이 오므로, 항상 참이되어 영역 내의 코드를 무한 반복합니다. 그렇다면, 이 무한 루프는 어떻게 쓰일까요? 아래는 무한 루프가 사용된 예입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int sum = 0;

            while (true)
            {
                Console.Write("수를 입력하세요: ");
                string line = Console.ReadLine(); // 값을 입력받는 부분!
                if (line == "end") break; // end가 입력되면 무한 루프를 빠져나온다.
                sum += int.Parse(line); // 문자열을 숫자로 변환한다!
            }

            Console.WriteLine("지금까지 입력된 수를 모두 더합니다: " + sum);
        }
    }
}
결과:
수를 입력하세요: 457
수를 입력하세요: 1006
수를 입력하세요: 422
수를 입력하세요: 14
수를 입력하세요: 33
수를 입력하세요: end
지금까지 입력된 수를 모두 더합니다: 1932
계속하려면 아무 키나 누르십시오 . . .

코드를 살펴보자면, 11행부터 while문이 등장합니다. 하지만 조건식에 참(true)이 오기 때문에 항상 참이라는 조건이 성립됩니다. while문 안을 살펴보면 사용자에게 입력받은 값을 line란 변수에 저장하는 부분과 end가 입력되면 루프를 빠져나오는 부분과, 문자열을 숫자로 변환하여 sum에 더하는 부분이 보입니다. 결과를 살펴보면 457+1006+422+14+33의 값 1932가 결과로 출력됩니다.

2. break

먼저 break문부터 소개하도록 하겠습니다. 이 break문은 전에 배웠던 switch문에서 빠져나오기 위한 break나, 방금 무한 루프에서 빠져나오기 위해 사용되었던 break가 있습니다. break는 그대로 '탈출하다'라는 의미를 지니고 있으며, 루프에서나 switch문에서 사용됩니다.

아래는 특정한 조건을 만족하면 break문을 사용하여 빠져나오는 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 0;

            while (num < 100) // num보다 100이 크면 계속 반복
            {
                if (num == 40) break; // num이 40이면 break로 인해 반복 탈출
                Console.WriteLine("num: " + num);
                num++; // num의 값 1 증가
            }
        }
    }
}
결과:
num: 0
num: 1
num: 2
num: 3
...
num: 38
num: 39
계속하려면 아무 키나 누르십시오 . . .

코드를 보시면 11행에서 while문이 등장하고, 조건식에 num < 100이 옵니다. 즉, 100이 num보다 크다면 반복 영역 내의 코드를 계속 실행합니다. 그리고 그 다음 15행에서는 num의 값이 40이라면 break문으로 인해 반복 영역을 빠져나옵니다. 40이 아니라면 if문을 무시하고 num의 결과를 출력한 뒤에 num의 값을 1 증가시키죠. 간단하죠?

3. continue

continue문은 조건을 검사하는 부분으로 넘어가 반복을 계속 수행하는 역할을 합니다. continue문을 만나면 바로 조건 검사부분으로 넘어간다는 말이죠. 쉽게 말해서, 한번 쉬고 계속 반복을 진행한다는 말과 같습니다. 예를 들면,
...
    for (int i = 0; i < 10; i++) {
        if (i == 7) continue;
        Console.WriteLine("i: " + i);
    }
...
for문을 만나 루프를 돌다가 i가 7이되면 continue문을 만납니다. continue문을 만나면 continue문 아래의 문장은 실행시키지 않고 한번 쉬고나서 반복을 계속 수행합니다. 아래는 for문에 continue문을 사용한 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 50; i++)
            {
                if (i % 2 == 1) continue;
                Console.WriteLine("i: " + i);
            }
        }
    }
}
결과:
i: 2
i: 4
...
i: 46
i: 48
i: 50
계속하려면 아무 키나 누르십시오 . . .

코드를 보시면, 9행에서 for문이 등장합니다. for문의 시작과 함께 i의 값은 1로 초기화 되고 그 영역 내의 코드를 실행합니다. 11행에서 i를 2로 나눴을때 나머지가 1이라면, 즉 홀수라면 continue문을 만나 한번 쉬고 계속 반복을 수행합니다. 만약에 짝수라면 if문을 무시하고 i의 값을 출력하게 되겠죠.

만약에, i가 3이라고 가정하고 11행에 있는 if문을 거친다고 해봅시다. 현재 i의 값은 3이므로, 3을 2로 나누고 나머지가 1이므로 i%2==1란 조건이 성립합니다. 조건이 성립하므로, if문 내의 continue문을 만나 i의 값이 1증가되고 다음으로 넘어갑니다. i가 홀수가 아니고 짝수라면 결과처럼 그대로 출력됩니다. 

4. goto

goto문은 해당 레이블로 뛰어넘어버리는 기능을 가지고 있습니다. 아래는 goto문의 사용 형식입니다.
...
goto 레이블;

...
레이블:
    // 실행될 코드
...
(여기서 레이블(Label)이란, 코드 내의 위치를 나타내주는 역할을 합니다.)

아래는 break문 예제에서 break문 대신 goto문이 사용된 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 0;

            while (num < 100) // num보다 100이 크면 계속 반복
            {
                if (num == 40) goto EXIT; // num이 40이면 break로 인해 반복 탈출
                Console.WriteLine("num: " + num);
                num++; // num의 값 1 증가
            }

            EXIT: // EXIT 레이블!
            Console.WriteLine("탈출!");
        }
    }
}
결과:
num: 0
num: 1
num: 2
num: 3
...
num: 38
num: 39
탈출!
계속하려면 아무 키나 누르십시오 . . .

코드를 보시면, 13행에서 break문이 goto EXIT;로 대체되었습니다. (goto EXIT를 만나면 EXIT 레이블로 건너뜁니다) goto문을 보면 상당히 편해보일수 있겠지만, 그렇다고 goto문을 많이 사용하면 프로그램의 흐름이 자주 끊어져 코드를 이해하기 어렵게 만들수 있습니다. 적당히 사용하는게 좋습니다.

이번 강좌는 여기서 마치도록 하겠습니다. 수고하셨습니다.

다음 강좌는 메소드(Method)에 대해 배워보도록 하겠습니다.

  1. 나그네 at 2012.09.13 13:16 신고 [edit/del]

    8강이 빨리 나왔으면 좋겠어요.. 정말 잘 보고 있습니다. 감사합니다.

    Reply
  2. 나그네 at 2012.09.13 13:56 신고 [edit/del]

    혹씨라도 개인지도 해주실수 있으시나요? 설명이 너무 좋아서 개인지도 받고 싶습니다.
    soundpop1@naver.com 으로 메일주세요.. 연락처도 함께 주시면 전화 드리겠습니다.
    감사합니다.

    Reply
  3. 김하섭 at 2012.09.14 13:51 신고 [edit/del]

    잘봤습니다 ^^ 알기쉽게 설명해 놓아서 정말 이해하기 쉬웠습니다

    Reply
  4. 김승현 at 2012.10.20 00:19 신고 [edit/del]

    감사합니다~

    Reply
  5. kes at 2013.04.18 18:48 신고 [edit/del]

    자바를 배우고 c#을 배우는데 강의 잘 보고 있습니다~
    Console.ReadLine이 자바의 Scanner와 같은기능이군요~
    설명이 너무 쉽게 잘되있어서 좋네요~

    Reply
  6. 열! 공! at 2013.07.30 13:48 신고 [edit/del]

    제가 초보라 잘모르는게있어서요....^^
    질문 두가지 부탁드립니다.

    첫 번째
    sum += int.Parse(line);
    위의 코드는 무엇을 의미하는건가요?

    int.Parse(line); -> 이표현을 제가 처음 봐서 잘 모르겠습니다.

    두 번째 입니다.
    Console.WriteLine("입력한 모든 수를 더합니다:", +sum);
    위의 문장이
    Console.WriteLine("입력한 모든 수를 더합니다: {0}", sum);
    다른점은 무엇인가요?

    그리고 전자로 사용하신 이유는 특별히 있나요?

    이상입니다....꼭!! 답변 부탁드립니다~

    Reply
    • BlogIcon EXYNOA at 2013.07.30 17:32 신고 [edit/del]

      sum += int.Parse(line);
      위에 쓰인 int.Parse 메서드는 문자열을 정수 형식으로 바꾸어 줍니다.

      Console.WriteLine("입력한 모든 수를 더합니다: " + sum);
      그리고 위에 쓰인 + 연산자는 문자열과 다른 피연산자를 연결하며,

      Console.WriteLine("입력한 모든 수를 더합니다: {0}", sum);
      위의 문장은 포맷을 통해서 뒤에 따라오는 인수인 sum이 치환자에 의해 {0} 자리에 출력됩니다.

      후자의 방법도 좋지만, 개인적으로 전자가 편해서 전자의 방법을 사용했습니다!

    • 열! 공! at 2013.07.30 18:02 신고 [edit/del]

      아하~ 제가 그위의 입력라인에서 string으로 입력받는 부분을 보지못했네요.....

      문자열로 입력을 받았으니 당연히 합을 구하려면 int로 바꿔줘야 하는 부분이 당연하네요...

      그러면 종료 이벤트가되는 'end'문자열 을 입력받기 위해 string으로 자료를 입력 받도록 작성하신거라 이해 해도 될까요??

  7. 차상협 at 2013.08.23 17:48 신고 [edit/del]

    연락처를 좀 알고 싶어서 문의 남깁니다 ^^

    강의 잘 보고 있습니다

    혹시라도 실례가 안된다면 shmg1000@naver.com으로 연락처 하나 주시면 감사하겠습니다.

    Reply
  8. 임영빈 at 2013.08.26 11:44 신고 [edit/del]

    Console.WriteLine 에서의 + 연산자에 의해 정수가 String 으로 (c에서의 strcat와 비슷하게 ) 바뀌는건가요?

    Reply
    • BlogIcon EXYNOA at 2013.08.26 16:55 신고 [edit/del]

      네 맞습니다. 두 피연산자의 형식이 정수인 경우에는 두 정수의 합을 계산하며, 하나 또는 두 피연산자가 문자열 형식인 경우는 피연산자를 서로 문자열로 연결시킵니다.

  9. ZiNee at 2013.10.13 18:54 신고 [edit/del]

    열공하기에 아주 좋은 노아님의 강의입니다. 감사합니다.

    Reply
  10. BlogIcon hankim at 2014.08.07 23:26 신고 [edit/del]

    2. break 문과 3. goto 에서

    17열에 Console.WriteLine("num" + num);

    에서 '+' 의 의미가 무엇인지 여쭤봐도 될까요?

    감사합니다.

    Reply
  11. BlogIcon 치리시 at 2014.10.16 11:16 신고 [edit/del]

    저같은경우는 레이블만드는게 편한경우도 있더군요. 50줄짜리 코드를 한묶음씩 만들어서 이용하는게 오히려... 움. 어짜피 다른사람한테 코드를 보여주는것도 아니고 이런때는 goto문을 사용하는것도 괜찮지는 않을지 생각되네요.

    Reply
  12. BlogIcon 치리시 at 2014.10.16 11:20 신고 [edit/del]

    추가로 음 제가 생각하는 goto문의 가장 안좋은 예시가 goto를 사용하면서 주석을 안달아놓은경우랄까요. 레이블도 알아보기 쉽구 주석을 달아놓으면 오히려 반복구문보다 알아보기 쉬운경우가 있더라구요... 저같은경우는 50줄짜리 두개 묶으려고 반복구문을 100줄짜리로 만든거 보면 극혐이거든요...ㄷㄷ..

    Reply
  13. 베리드 at 2015.01.04 21:16 신고 [edit/del]

    정말 감사합니다 아무리 책을 봐도 이해가 안되고 그랬는데...
    되게 간단하게 핵심만 있는 강의네요 정말 매강의 마다 이해가 잘되고 있습니다!

    Reply
  14. 초보 at 2016.01.08 23:19 신고 [edit/del]

    온라인강좌에서 없는 내용이 있어 유익하게 잘 보고 있습니다.

    Reply
  15. 고훈 at 2016.09.17 10:05 신고 [edit/del]

    감사합니다.^^
    얻는 게 많고 이해가 쉽습니다..

    Reply
  16. 은밤 at 2017.03.06 11:04 신고 [edit/del]

    머릿속에 속속들어오는 강의 감사합니다~^^

    Reply
  17. dbswo5092 at 2017.05.31 13:46 신고 [edit/del]

    사랑해요

    Reply

submit


1. while(참일때 동안 반복~)


오늘은 반복문에 대해서 알아보도록 할 텐데, 여기서 반복문이란 말 그대로 반복에서 쓰이는, 특정 조건을 만족할 때 까지 계속 반복하여 실행하는 문장입니다. 우선은 while문부터 알아보도록 하겠습니다. 아래는 while문의 기본 형태입니다.

while (조건식) {
    // 반복 실행될 코드
}

위와 같은 형태에서 조건식은 if문과 마찬가지로 true 또는 false가 반환되어야 합니다. while문의 특징은 조건식이 참일 때 동안 계속해서 반복하여 코드를 실행합니다. 만약에 반복하다 조건식이 거짓이 되면 루프를 빠져나옵니다. (여기서 루프란 프로그램의 실행 흐름이 고리처럼 이어지는 부분을 말합니다. 즉, 반복되는 부분을 말함) 그러나 계속 조건식이 참이라면 루프를 빠져나오지 못하고 계속 반복하게 되는 무한 루프에 빠집니다.


아래는 while문을 사용하여 num이 10보다 커질때까지 반복하는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 1;

            while (num <= 10)
                Console.WriteLine("num: {0}", num++);
        }
    }
}
결과:
num: 1
num: 2
num: 3
num: 4
num: 5
num: 6
num: 7
num: 8
num: 9
num: 10
계속하려면 아무 키나 누르십시오 . . .

위의 예제를 설명하자면, 정수형 변수 num을 선언하고 그와 동시에 1이란 값으로 초기화시켰습니다. 그러곤 while문이 등장하여 num이 10보다 커질 때까지 반복을 하죠. num이 11이 된다면 조건식을 만족하지 못하고 그대로 빠져나와 버립니다. 그리고 그다음에 등장하는 12행에서 인수를 보아하니 num++라는게 왔습니다. 이것은 우리가 전에 배운 증감 연산자이며, 자세히 말하자면 후위 증가 연산자입니다. num의 값을 우선 출력하고 그제서야 num의 값이 1만큼 증가하죠.

만약에 num의 값을 증가하는 부분을 빼버린다면 어떤일이 발생할까요?
...
            while (num <= 10)
                Console.WriteLine("num: {0}", num);
...
결과:
num: 1
num: 1
num: 1
num: 1
num: 1
num: 1
...

그대로, num의 값이 1에서 항상 머무르기 때문에 조건식을 항상 만족하고 num의 값을 출력합니다. 이런 무한 루프는 어찌 보면 골칫덩어리지만 또 어찌 보면 유용하게 사용될 수 있는 부분입니다. 무한 루프에 대해서는 나중에 다시 한번 설명해드리겠습니다.

2. do~while(한번은 먼저 실행 후 반복~)

조건식을 먼저 검사하고 코드를 실행하는 while문과는 달리 do~while문은 먼저 한번 코드를 실행시키고 그다음에 조건식을 검사합니다. 다음은 do~while의 기본적인 형태입니다.
do {
// 반복 실행될 코드
} while (조건식); // 여기서 주의하실 것은 마지막에 세미콜론이 붙는다는 겁니다.
꼭 기억하셔야 할 것은, do~while문을 사용하면 조건식을 만족하든 만족하지 않든 반드시 한번은 실행이 된다는 겁니다. 아래는 위의 while문 예제를 do~while문으로 다시 구현 한 것입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 1;

            do
            {
                Console.WriteLine("num: {0}", num++);
            } while (num <= 10);
        }
    }
}
결과:
num: 1
num: 2
num: 3
num: 4
num: 5
num: 6
num: 7
num: 8
num: 9
num: 10
계속하려면 아무 키나 누르십시오 . . .

결과를 보아선 아까의 while문을 사용했을 때의 결과와 다른 게 없습니다. 그러나 우리가 프로그램을 만들다 보면 우선 검사하고 나중에 실행하는 while문이 아닌 먼저 실행하고 나중에 검사하는 do~while문이 필요할 때가 있습니다. 꼭 한번은 실행시키고 검사를 해야 하는 상황이 발생했을 때 유용하게 쓰이죠.

3. for(참이 될 때까지 반복~)

for문은 while문과 같이 특정 조건을 만족할때까지 반복에 쓰입니다. 비교해보면 for문은 while문보다 쓰기도 쉽고, 초기화 부분과 증감 부분이 따로 놀지도 않습니다. 아래는 while문과 for문을 비교한 것입니다.
for(초기식; 조건식; 증감식) {
    // 반복해서 실행될 코드
}
초기식;

while(조건식) {
    // 반복해서 실행될 코드
    증감식
}
확실히 간편하죠? 여기서 초기식에는 반복을 실행하기 전 반복문에서 사용될 변수를 초기화하는 부분입니다. 조건식은 그대로 반복 여부를 결정하는 부분이고, 증감 식은 반복문을 빠져나오기 위하여 어느 변수의 값을 감소시키거나 증가시키는 부분을 말합니다. 아래는 while문, do~while문에 쓰였던 예제를 for문으로 다시 구현 한 것입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int num = 1; num <= 10; num++)
                Console.WriteLine("num: {0}", num);
        }
    }
}
결과:
num: 1
num: 2
num: 3
num: 4
num: 5
num: 6
num: 7
num: 8
num: 9
num: 10
계속하려면 아무 키나 누르십시오 . . .

예제를 보시면 바로 for문이 등장하고 있습니다. for문의 실행흐름을 보자면 이렇습니다.

초기식 -> 조건식 -> 코드 실행 -> 증감식 -> 조건식 -> 코드 실행 -> 증감식 -> ...

우선은 초기식에 num이란 변수가 선언되고 1이란 값으로 초기화됩니다. 이 초기식은 단 한 번만 실행되며, 여기서 선언된 num이란 변수는 for문이 끝나면 알아서 소멸합니다. 그다음에 조건식을 거칩니다. num이 10보다 작거나 같으면 조건을 만족하고 코드 실행부로 넘어갑니다. 그다음 코드가 실행되고 증감식으로 넘어가 num의 값이 1만큼 증가한 뒤에 다시 조건식으로 돌아와 검사하고 코드가 실행되고 증감식으로 넘어가는 걸 반복하죠. 그러다 조건을 만족하면 for문을 빠져나오는 것입니다. 이해되셨죠?

4. foreach(순회하며 차례대로 접근~)

아직은 foreach문을 이해하시기에는 문제가 있을 수 있습니다. foreach문을 배우려면 배열과 컬렉션을 알아야 하기 때문이죠. 이 부분을 건너뛰어 배열과 컬렉션을 배우시게 될 때 참고하셔도 좋습니다. 그러나 굳이 지금 이해하고 싶다고 하시는 분들은 말리지 않겠습니다.

우리가 여태까지 배운 변수는 하나의 값만 저장할 수 있었습니다. 하지만 지금 보게 될 배열은 동일한 성격의 변수들이 일렬로 서있다고 생각하시면 됩니다. 간단히 변수 여러 개를 한곳에 가져다가 붙였다고 생각합시다. 여기서 그만, 배열은 나중에 알아보도록 하고 foreach의 설명을 이어가도록 하겠습니다.

기본적인 foreach문의 형태는 아래와 같습니다.
foreach (변수 in 배열 혹은 컬렉션) {
    // 실행될 코드
}
아래는 foreach문의 이해를 돕기위해 작성된 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] arr = { 1, 2, 5, 7, 4, 9, 8, 10, 4, 7, 11 };

            foreach (int i in arr)
                Console.WriteLine("i: {0}", i);
        }
    }
}
결과:
i: 1
i: 2
i: 5
i: 7
i: 4
i: 9
i: 8
i: 10
i: 4
i: 7
i: 11
계속하려면 아무 키나 누르십시오 . . .

코드와 결과를 번갈아 보아하니, 14행에 등장하는 foreach문은 배열에 담겨있는 각각의 데이터를 순회하면서 변수 i에 집어넣습니다. 그 전에 9행을 보시면 int에 []가 붙고 괄호 내에 데이터들이 각각 콤마를 기준으로 하여 등장합니다. 여기서 각각의 데이터들을 '요소'라고 부릅니다. 나중에 다차원 배열도 함께 배우는데 이 다차원 배열에서도 foreach문이 사용될 수 있습니다.

5. 반복문의 중첩

우리가 지금까지 배운 while, for, do~while문은 if문 처럼 중첩이 가능합니다. for문 안에 for문이 사용될 수도 있고, for문 내에 while문이 사용될수도 있습니다. 상황에 따라서는 for문이 3번 이상 중첩될 수 있죠. 그중에서 많이 쓰이는 중첩이 for문의 중첩입니다.
for(...; ...; ...) {
    for(...; ...; ...) {
        ...
    }
}
다음은 for문을 두 번 사용하여 구구단을 출력시키는 예제입니다
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int a = 2; a < 10; a++)
            {
                for (int b = 1; b < 10; b++)
                {
                    Console.WriteLine("{0} * {1} = {2}", a, b, a * b);
                }
            }
        }
    }
}
결과:
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
...
9 * 5 = 45
9 * 6 = 54
9 * 7 = 63
9 * 8 = 72
9 * 9 = 81
계속하려면 아무 키나 누르십시오 . . .

단 for문을 두 번만 사용하였을 뿐인데 반복을 72번 수행하여 그 많던 구구단을 단번에 출력시켰습니다. 이렇게, 중첩을 잘 사용하면 더욱더 편하게 프로그램을 제작할 수 있습니다.

이제 그만 반복문에 대한 강좌는 여기서 마치도록 하겠습니다. 수고하셨습니다.

다음 강좌에서는 무한 루프, continue, break, goto에 대해서 알아보도록 하겠습니다.

  1. 언제나좋은날 at 2012.09.04 09:45 신고 [edit/del]

    C#을 새로 배우려 하는데
    잘보았습니다.

    Reply
  2. 곰팅 at 2012.09.05 15:52 신고 [edit/del]

    앞으로도 계속 부탁드립니다.

    Reply
  3. 김승현 at 2012.10.20 00:09 신고 [edit/del]

    감사합니다~

    Reply
  4. 쩨이 at 2013.01.24 05:24 신고 [edit/del]

    엑시노아님 C# 강좌의 갑! 완전 초보인데, 그림과 함께 설명을 너무 잘해주셔서 차근차근 읽어보며 잘 따라하고있는것 같습니다. 이런 소중한 자료와 노고에 감사드립니다 *^^*

    Reply
    • BlogIcon EXYNOA at 2013.01.24 11:12 신고 [edit/del]

      아직 강좌 쓰는게 미숙하여 제대로 도움이 되었는지 모르겠습니다.
      틀린 부분은 지적해주시고, 추가해야 할 부분이 있으면 언제든지 말해주세요. 감사합니다. ^ㅡ^!

  5. ㅇㅇ at 2013.05.22 14:59 신고 [edit/del]

    ASP.NET과 C#까지 연동해서 볼 수 있어 좋네요. 항상 감사히 보고 있습니다.

    Reply
  6. ZiNee at 2013.10.13 18:26 신고 [edit/del]

    노아님의 강좌는 명불허전입니다. 다시 한번 고개 숙여 감사의 마음을 표합니다. (--)(__)

    Reply
  7. xcsoft at 2014.12.25 16:39 신고 [edit/del]

    for는 거짓일동안 반복이아닌가요?

    Reply
  8. Harrison at 2017.02.27 18:25 신고 [edit/del]

    do ~ while문의 예제에 오류가 있습니다. 의도하신 것과는 다르게 11까지 출력됩니다. 다른 분들이 혼동하실까봐 적습니다. 좋은 강좌 감사합니다.

    Reply

submit


1. if~else문 (만약에~, 그렇지 않으면~)


오늘은 조건문에 대해서 알아보도록 하겠습니다. 여기서 조건이란 사전적 의미 그대로 '어떤 일을 이루게 하거나 이루지 못하게 하기 위하여 갖추어야 할 상태나 요소'라는 뜻을 지니고 있습니다. 프로그래밍에서 프로그램 흐름을 조건에 따라 실행시키는 게 바로 우리가 배울 '조건문'입니다. 우선 if문 부터 배워보도록 하겠습니다. 아래는 if문의 기본 구성입니다.

if (조건식) {
    // 조건이 참일 경우 실행될 문장
}

이 예제의 조건식에서 true 또는 false를 반환하는 논리 연산자나 관계 연산자가 자주 등장합니다. 조건식에 올 수 있는 건 true 또는 false의 값을 가지는 bool 형식이어야 합니다. 예를 들어, 아래의 조건을 한번 살펴봅시다.

if (a > b) {
    Console.WriteLine("a가 b보다 큽니다.");
}

a가 b보다 클 경우에 조건식은 참(true)이 되고, 그 영역의 문장을 실행시킵니다. 만약에 b가 a보다 크다면 거짓(false)이 되어 이 조건문은 무시해버리고 넘어가 버리겠죠.


무엇보다 이렇게 설명을 듣는 것보다 직접 보는 것이 빠릅니다. 아래는 if문을 사용하여 a와 b 중 무엇이 더 큰지 가려내는 예제입니다. 직접 작성하시고 다른 방법으로도 응용해보시는 것을 권장합니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50;
            int b = 51;

            if (a < b) // 참고: 실행될 문장이 한줄이라면 괄호가 없어도 됨.
                Console.WriteLine("b가 a보다 큽니다.");
            if (a > b)
                Console.WriteLine("a가 b보다 큽니다.");
        }
    }
}

결과:

b가 a보다 큽니다.

계속하려면 아무 키나 누르십시오 . . .


코드를 간단히 살펴보자면, 정수형 변수 a와 b라는 변수가 선언되고 그와 동시에 50과 51이란 값으로 각각 초기화 되었습니다. 그 다음에 if문이 등장하여 a와 b의 크기를 비교하는 연산자가 조건식 내에 등장합니다. b(51)이 a(50)보다 크므로 결과에서 "b가 a보다 큽니다."라고 출력된 것입니다.


위의 코드를 대충 보기엔 코드에 아무런 문제가 없습니다. 그런데 12행과 14행에 쓰인 2개의 if문은 사실상 올바르지 못한 조건문의 사용이라 볼 수 있습니다. b가 a보다 크다면 a가 b보다 작다는 말이 됩니다. 즉, b가 a보다 크다면 a가 b보다 큰지 아닌지 가려내는 14행의 if문은 쓸모가 없습니다. (CLR이 두 개의 조건 검사를 수행하는 것과 같음)


그럼 어떻게 해야 할까요? 바로 else문을 이용하시면 이를 쉽게 해결하실 수 있습니다. else문은 '그렇지 않으면~' 발생하는 영역입니다. 만약에 a < b가 거짓이라면 else문 내의 문장이 실행되겠죠? else문의 기본적인 사용 형태는 아래와 같습니다.

if (조건식) {
    // 참일 경우에 실행될 문장
} else {
    // 위의 조건식에 아무것도 해당하지 않을때 실행될 문장
}

아래는 17행의 if문을 else문으로 변경하여 작성한 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50;
            int b = 51;

            if (a < b)
                Console.WriteLine("b가 a보다 큽니다.");
            else
                Console.WriteLine("a가 b보다 큽니다.");
        }
    }
}
위 코드는 정상적으로 제 기능을 수행하고 있는것처럼 보이나 사실상 문제가 있습니다. 12행의 조건식인 a < b를 역으로 바꾸게 되면 a >= b가 됩니다. 지금 저 코드에서는 a와 b가 서로 같아도 "a가 b보다 큽니다"가 출력됩니다. 이것은 else if문을 사용하면 쉽게 해결할 수 있습니다. 참고로 else if는 if문에 종속적이므로 else if문이 등장하기전 if문이 반드시 등장해야 합니다. 아래는 else if문의 기본적인 사용 형식입니다.
if (조건식) {
    // 참일 경우에 실행될 문장
} else if (조건식) {
    // 참일 경우에 실행될 문장
} else {
    // 위의 조건식에 아무것도 해당하지 않을때 실행될 문장
}
아래는 if문과 else문 사이에 else if문을 추가하여 다시 작성한 예제입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50;
            int b = 50;

            if (a < b) // a가 b보다 작을 경우!
                Console.WriteLine("b가 a보다 큽니다.");
            else if (a == b) // a와 b가 같을 경우!
                Console.WriteLine("a와 b는 서로 같습니다.");
            else // 그 외의 경우!
                Console.WriteLine("a가 b보다 큽니다.");
        }
    }
}
결과:
a와 b는 서로 같습니다.
계속하려면 아무 키나 누르십시오 . . .

이제 정상적으로 결과가 출력되는 것을 확인하실 수 있습니다. 그리고 한 가지 더 알아두셔야 할 게 있는데, 그것은 바로 if문의 중첩입니다. 중첩은 나중에 배울 반복문(for, while~)에서 자주 사용됩니다. 아래는 if문의 중첩 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 50;

            if (a > 0)
            {
                Console.WriteLine("a는 양수입니다.");
                if (a > 30)
                    Console.WriteLine("a는 30보다 큽니다.");
            }
            else
                Console.WriteLine("a는 양수가 아닙니다.");
        }
    }
}
결과:
a는 양수입니다.
a는 30보다 큽니다.
계속하려면 아무 키나 누르십시오 . . .

코드를 보면, if문 내에 또다시 if문이 사용되신 것을 보실 수 있습니다. if문은 예제에서 보여준 것처럼 꼭 두 번만 가능한 것이 아니고, 여러 번 중첩이 가능합니다. 만약에 "a는 30보다 큽니다."라는 문장이 출력되려면 a는 0보다 커야하며 30보다도 커야 합니다. 만약에 0보다 크고 30보다 작다면 "a는 30보다 큽니다."라는 문장이 출력되지 않겠죠. 이해되셨나요?

2. switch, label, break

이제 switch문에 대해 배워보도록 하겠습니다. switch문은 if문과 달리 여러 개의 조건식의 결과를 검사할 때 사용됩니다. 기본적인 switch문의 형태는 아래와 같습니다.
switch (조건식) {
    case 상수: // 만약 조건식의 결과가 이 상수와 같다면!
        // 실행될 코드
        break; // 탈출!
    case 상수:
        // 실행될 코드
        break;
    ...
}
이해를 돕기위해 예를 하나 들겠습니다. 만약에 조건식에 a % 2가 온다고 하고 a의 값이 13이며, 이 a가 홀수인지 짝수인지 구별하는 프로그램을 만들어 본다고 칩시다.
switch (a % 2) {
    case 0:
        Console.WriteLine("짝수입니다!");
        break;
    case 1:
        Console.WriteLine("홀수입니다!");
        break;
}
이 경우에는 a를 2로 나눴을 때 나머지 값이 0이냐, 1이냐에 따라 나뉘는데 만약 0이라면 case 0:으로 이동하여 그 영역에 있는 문장을 실행시키고 break문을 만나 탈출합니다. 1이면 case 1:로 이동하겠죠. 참고로, switch문은 정수 형식과 문자, 문자열 형식만을 지원한다는 것을 알아두시면 좋겠습니다.

여기서 코드에 쓰인 break문이 어떤 역할을 하는지 모르시는 분이 있으신데, break문에 대한 이해를 위해 break를 주석 처리하고 아래 코드를 컴파일 하게되면 다음과 같은 오류가 발생합니다.

오류 1 한 case 레이블('case 0:')에서 다른 case 레이블로 제어를 이동할 수 없습니다. C:\Users\su6net\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs 16 17 ConsoleApplication1
...

C언어에서는 break문이 없으면 그 아래 영역까지 모조리 실행되는 참사가 일어났으나, C#에서는 break문이 없다면 다른 레이블로 이동할 수 없다며 오류를 내보냅니다. 이 break문은 우리가 작성한 코드를 실행하고 그 영역을 빠져나오기 위해서 작성해주는 문장입니다. 나중에 반복문에서도 등장합니다.  

아래는 문자열을 검사하여 해당 부분으로 이동하는 예제입니다.
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            String day = "수";

            switch (day)
            {
                case "일":
                    Console.WriteLine("일요일");
                    break;
                case "월":
                    Console.WriteLine("월요일");
                    break;
                case "화":
                    Console.WriteLine("화요일");
                    break;
                case "수":
                    Console.WriteLine("수요일");
                    break;
                case "목":
                    Console.WriteLine("목요일");
                    break;
                case "금":
                    Console.WriteLine("금요일");
                    break;
                case "토":
                    Console.WriteLine("토요일");
                    break;
                default:
                    Console.WriteLine("아무 요일에도 해당하지 않습니다.");
                    break;
            }
        }
    }
}
결과:
수요일
계속하려면 아무 키나 누르십시오 . . .

코드를 보시면, 문자열 변수 day에 담긴 값에 따라 switch문으로 인해 해당 부분으로 이동합니다. 만약에 "수"가 아닌 "가"처럼 해당하는 부분이 없을 경우에는 default: 영역으로 이동합니다. 여기서 default는 if문의 else와 비슷하다 생각하시면 이해하기 쉽습니다. 말 그대로 기본이 되는 영역이죠. 해당되는 영역이 없으면 이 기본 영역으로 이동하게 되는것 입니다.

조건문 강좌는 여기서 마치도록 하겠습니다. 수고하셨습니다.

다음 강좌는 반복문(while, do, for)에 대해 알아보도록 하겠습니다.

  1. 김승현 at 2012.10.19 23:59 신고 [edit/del]

    감사합니다~

    Reply
  2. C#초보 at 2013.01.02 16:38 신고 [edit/del]

    감사합니다 잘봤습니다 정말감사합니다!

    Reply
  3. BlogIcon 오류 at 2013.01.05 04:52 신고 [edit/del]

    b가 a보다 크다면 a가 b보다 작다는 말이 됩니다.
    하지만 a와 b가 같을수도있죠 ㅇㅇ;

    Reply
  4. 전세계 at 2013.02.13 13:37 신고 [edit/del]

    감사합니다. 아직 이해는 잘안되지만 정주행 해보렵니다.

    Reply
  5. C#입문자 at 2013.04.03 17:31 신고 [edit/del]

    자세하게 잘 설명해주셔서 이해가 쉽게 되네요. 감사합니다!! 끝까지 정주행 하도록 하겠습니다. ^^

    Reply
  6. ZiNee at 2013.10.13 17:52 신고 [edit/del]

    저도 끝까지 정주행하겠습니다. 좋은 강좌 올려주셔서 감사합니다.

    Reply
  7. 응애 at 2014.07.04 14:15 신고 [edit/del]

    C#처음시작한 애기입니다 강좌 고맙습니다.

    Reply
  8. 심사람 at 2016.07.12 09:00 신고 [edit/del]

    잘 배우고 있습니다. 하나 궁금한 것이 C#에는 C처럼 scanf기능이 없나요? 혹시 있다면 알려주실 수 있으신지요?

    Reply
  9. at 2017.03.31 09:33 신고 [edit/del]

    Vb의 select case문이였군요~

    Reply
  10. 엄청나군요 at 2017.07.07 14:06 신고 [edit/del]

    다른 c언어를 하나도 모르는 사람입니다. 하지만 글이 너무 쉽게 되있어 저 같은 초심자도 이해하기 쉽군요. 정말 감사합니다. 실례가 되지 않는 다면 질문 두어가지만 해도 될런요? 첫번째는 if 문에서 중첩이 가능하다고 하셨는데 만약 제가 다음과 같이 식을 짠다고 해도 성립에 되는 것인지 궁금합니다.
    int a = 5
    if(a>0){
    Console.WriteLine("a는 양수");
    if(a>3)
    Console.WriteLine("a는 3보다 큼);
    }else if(a<0){
    Console.WriteLine("a는 음수");
    if(a<-3)
    Console.WritLine("a는 -3보다 작음);
    } else
    Console.WriteLine("a는 0과 같음);

    요지는 else if의 조건식 하위에 다시 if문이 중첩되어 사용될 수 있는 지의 여부입니다.

    두번째 질문은 switch문에서 case 상수 옆에 콜론이 붙는 데 그 다음줄에 바로 명령문이 오는 것으로 보입니다. 이 때는 중괄호가 원래 필요가 없는 것인가요? 아니면 명령문이 한줄이라 중괄호가 생략된 것 인가요?

    글 재간이 없어 질문의 형식이 이상할지 모르겠습니다. 가능하시다면 답변해주시면 정말 감사하겠습니다. 이렇게 저와같은 초심자들을 위해 보기 쉽게 정리해주셔서 감사할 따름입니다. 앞으로도 글쓴님의 좋은 글 보며 열심히 공부할게요^^

    Reply

submit

티스토리 툴바