[SBS게임아카데미] 1인개발 프로그래밍 (C#, 유니티)

[5] C# 제어문, 별 찍기, 배열 (SBS게임아카데미 4일차_230702_일)

개발린마케터 2023. 7. 15. 20:13
반응형

오늘은 제어문부터 시작. 

 

[제어문]

(1) break

 

예시1) break의 활용

            for (int i = 0; i < 5; i++)
            {
                if (i == 3)
                {
                    Console.WriteLine("브레이크");
                    break;//반복문의 조건과 상관없이 반복문 종료
                }
                else Console.WriteLine(i);
            }

i=0으로 시작해서, 5보다 작으면 1씩 늘려가다가 

i=3이 되면 break! 말 그대로 반복문을 종료하는 제어문이다.

3에서 break 동작!

예시2) 또 다른 break 활용

           for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (j == 3) break; //내부 반복문만 종료
                    else
                    {
                        Console.WriteLine("i:{0}, j:{1}", i, j);
                    }
                }
            }

2개의 변수가 있고, i가 0부터 1씩 커지는 상황 속에서

j도 0부터 커지다가 j=3이 되면 바로 종료되어 버린다.

(여기서 난 완전히 모든 반복문이 종료될 거라고 생각했다...)

 

그럼 다시 위로 올라가 다시 i가 1 커진 상황 속에서

j=0부터 반복문 시작, 그리고 j=3이 되면 종료. 

이렇게 반복된다. 

신비한 컴퓨터의 사고처리 방식이란...

(2) Continue

두번째 제어문은 continue이다. 

continue 이후의 코드들은 실행하지 않고 반복문을 재실행하는 제어문이다.

 

예시1) 단순 반복 중의 활용

            for (int i = 0; i < 5; i++)
            {
                if (i == 3) continue;       //continue 이후의 코드들은 실행하지 않고 반복문을 재실행!

                Console.WriteLine(i);
            }

일종의 예능용 게임 중의 "패스!!!" 느낌이다. 

순서대로 진행하다가 "요건 패스" 하고 넘어가게 된다. 

3은 패스!!!

예시2) 2개의 변수 반복문 속의 활용

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (j == 2) continue;

                    Console.WriteLine("i:{0}, j:{1}", i, j);
                }

                Console.WriteLine();

            }

위에서 break의 예시2와 동일한 형식이다. 

반복적으로 i와 j가 커지다가 j가 2인 상황일 때만 패스!!!

j가 2일 때만 패스!!!

예시3) 비슷한 상황 속 또 다른 활용

 

            for (int i = 0; i < 5; i++)
            {
                if (i % 2 == 0) continue;     //i 나누기 2의 나머지 값이 0이라면 

                for (int j = 0; j < 3; j++)
                {
                    Console.WriteLine("i:{0}, j:{1}", i, j);
                }
                Console.WriteLine();
            }

i가 홀수일 때만 출력이 된다. 

i가 1,3일 때만 출력이 됐다

****** 예제 ******

반복문을 활용해서 100개의 난수를 발생 시키고, 
홀수와 짝수를 구분해서 각각 몇개인지 카운트 한 후 출력하라! 

<내가 푼 것>

 

일단 처음에 문제를 듣고, 한참 헤메었다. 

"아직 카운트 하는 건 배운 적이 없는데 어떻게 숫자를 세라는 거지?"

 

고민고민하다가 일단 바드(bard.google.com)에 물어봤다. 

이렇게... 알려주었다... 

            // 100개의 난수를 생성합니다.
            int[] randomNumbers = new int[100];
            for (int i = 0; i < 100; i++)
            {
                randomNumbers[i] = new Random().Next(0, 100);
            }

            // 홀수와 짝수를 구분해서 카운트합니다.
            int oddCount = 0;
            int evenCount = 0;
            for (int i = 0; i < 100; i++)
            {
                if (randomNumbers[i] % 2 == 1)
                {
                    oddCount++;
                }
                else
                {
                    evenCount++;
                }
            }

            // 홀수와 짝수의 개수를 출력합니다.
            Console.WriteLine("홀수: {0}", oddCount);
            Console.WriteLine("짝수: {0}", evenCount);

와... 무진장 화려하다... 

역시 무언가 카운트 하는 걸 배우지 않았는데 선생님이 잘못 문제를 내신 건가???

바드 선생님이 알려주신대로 일단 넣어보았다.

젠장... 오류난다... 

하지만 빨랐죠...

 

한참을 헤메고 있었는데 왜 하필 반복문을 한참 하고 나서 이게 나왔을까를 고민하다가...

그리고 위에서 홀수 일 때만 출력하게 했던 것도 떠오르다가... 

 

문득 아이디어가 떠올랐다. 

랜덤으로 나오게 하는 숫자 따로 나오고 출력시키고, 

카운트는 나오지는 않지만 따로 계속 카운트가 매번 올라가다가 

마지막에 출력 시키면 되겠다는 생각이었다. 

            Random ran = new Random();

            int b = 0;
            int c = 0;
            for (int i = 1; i < 101; i++)
            {
                int a = ran.Next(1, 101);
                Console.WriteLine(a);
                if (a % 2 == 0)
                {
                    b++;
                }
                else if (a % 2 == 1)
                {
                    c++;
                }
            }
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine(b);
            Console.WriteLine(c);

짜잔!!! 정말 한참 돌아왔다... 그래도 나와서 다행...

이거 하나 푸는데 정말 오래 걸렸... 

하지만 풀고 나서는 내가 정말 프로그래머라도 된 것 마냥 기분이 들떴다. 

 

<선생님이 푼 것>

            Random ran = new Random();                        //난수생성
            int count = 0;                                    //짝수 카운트 변수

            for (int i = 0; i < 100; i++)                     //100회 반복
            {
                if (ran.Next(1, 101) % 2 == 0) count++;       //생성한 난수 값을 2로 나누어 나머지 값이 0이라면 짝수이므로 count 1 증가

                if (i == 99) Console.WriteLine("홀수:{0}, 짝수: {1}", 100 - count, count);
            }

와... 간결... 

그렇다... 문제에 난수를 발생시키라고만 했지 굳이 출력하라는 말은 없었다... 

그리고... 하나만 세면 나머지 하나는 100에서 빼면 되는 것이었다... 

 

이 문제를 풀면서 프로그래밍을 배운 다는 것은 단순히 어떤 공식을 배우거나 사용법을 배우는 것이 아닌

하나의 사고 체계, 사고하는 방식을 배우는 것이다라는 생각이 강하게 들었다. 

 

[별 찍기]

아래와 같이 별이 찍히게 해보자

 

*

**

***

****

*****

 

아래와 같이 푸는 방법을 일단 배워보자

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < i + 1; j++)
                {
                    Console.Write("*");     //별찍기
                }
                Console.WriteLine();        //개행
            }

아름답다...

 

*** 예제 ***

반대로 찍어보자

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

<내가 푼 것>

            for (int i = 5; i > 0; i--)
            {
                for (int j = 0; j < i; j++)
                {
                    Console.Write("*");
                }
                Console.WriteLine();
            }

i가 5에서 하나씩 줄어야 한다고 생각했고 그것보다 j가 작을 때 찍는 형태로 풀어냈다. 

 

<선생님이 푼 것>

            for (int i = 0; i < 5; i++)
            {
                for (int j = 5; j - i > 0; j--)
                {
                    Console.Write("*");
                }
                Console.WriteLine();
            }

선생님은 i가 0부터 커지는 형태로 했고,

대신 J가 5에서 작아지게 하면서 j-i가 0보다 크다는 조건을 넣는 형태로 풀어냈다.

각각 푸는 방식은 달라도 출력은 동일!

*** 다음 예제 ***

아래와 같이 찍어보자.
(별것 아닌 변화 하나로 난이도가 확 올라갔다...)

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

<내가 잘못 푼 것> 

 

처음엔 정말 쉽게 생각했다.

위에 있던 예제와 동일한 위치에 빈칸이 찍히고 나머지 위치에 별만 찍히면 되네? 하고 생각해서 위에 똑같이 쓰고 별 대신 빈칸을 넣고는... 

그대로 얼음... 

그 뒤에 어떡하지???

 

한참을 고민하다가 싹 지우고 다시 고민...

            for (int i = 5; i > 0; i--)
            {
                for (int j = 0; j < i; j++)
                {
                    Console.Write(" ");
                    if (j == i - 1)
                    {
                        Console.Write("*");
                    }
                }
                Console.WriteLine();
            }

처음으로 별이 찍히는 위치가 4,3,2,1 이런 형태로 생각해서 그렇게 찍히는 반복문을 써보았다. 

하아... 멘붕...

그 뒤로 무엇을 바꿔볼까? 이래저래 고민만 하다가 주어진 시간이 다 지나버렸다. 

결국 못 풀어냄. 

 

다시 한번 느낀 점... 

사고 방식. 문제를 풀어내는 방법이야 말로 프로그래밍의 꽃이다... 

근데 하나에 잘못 꽂히면 그 사고를 풀어내고 원점에서 다시 고민하는 건 정말 어려운 일이다. 

 

<선생님이 푼 것>

            for (int i = 5; i > 0; i--)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (j + 1 >= i) Console.Write("*");
                    else Console.Write(" ");
                }
                Console.WriteLine();
            }

우와... 나는 숫자가 딱 나오게 해버려서 별이 그 위치에 하나만 찍혔다.

그 다음부터는 그 위치 이후로 어떻게 별을 다시 반복을 시켜야 하지? 고민하다가

수식을 너무 복잡하게 암산을 굴리다 머리가 계속 꼬여버렸었는데... 

의외로 심플한 것이었다. 

보고 싶었다... 이 아름다운 녀석...

*** 예제 ***

요렇게 찍어보자. (ㅠㅠ)

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

선생님이 바로 풀어주셨다. 

위 내용에서 약간의 응용. 

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (j >= i) Console.Write("*");
                    else Console.Write(" ");
                }
                Console.WriteLine();
            }

 

[배열 Array]

            int a;
            int[] array = new int[8];       //int배열 타입. array 변수에 크기가 8인 int 배열타입을 생성해서 참조. 연결. 대입. 할당.
                                            //생성한 배열의 메모리 주소를 변수에 대입. 할당.
                                            
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = i;           //i의 값에 해당하는 배열 공간에 접근 후 i의 값을 배열 공간에 대입. 할당.
                Console.WriteLine(array[i]);
            }

배열부터는 옮겨적기 바빠...

위 내용에 이어서 아래 내용을 쓰다 보면...

            array[3] = 40;
            array[6] = 100;
            array[7] = 30;
            array[8] = 10000;         //배열의 크기를 넘어서 접근하면 오류!! out of range

배열의 크기를 8로 지정했기 때문에 0~7까지만 지정이 가능하다 8번(9번째)는 지정 불가!

 

다음 예제. 

            int[] arr2 = new int[] { 5, 2, 12, 6, 10 };             //{ 5, 2, 12, 6, 10} 요소 수 만큼 배열의 크기가 정해짐

            for (int i = 0; i < arr2.Length; i++)
            {
                Console.WriteLine(arr2[i]);
            }

배열한 대로 잘 나왔다

또 다른 예제.

            int[] arr3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            foreach (int i in arr3) Console.WriteLine(i);

순차로 1~9가 나왔다

살짝 변형. 

            int[] arr2 = new int[] { 5, 2, 12, 6, 10 };            

            for (int i = 0; i < arr2.Length; i++)
            {
                Console.WriteLine(arr2[i]);
            }

            Console.WriteLine();

            int[] arr3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            foreach (int i in arr3) Console.WriteLine(i);

            arr2 = arr3;

            Console.WriteLine("arr2에 arr3의 값을 대입 후");

            foreach (int i in arr2) Console.WriteLine(i);

여기서 살짝 이해가 힘들었다. 

arr2는 5, 2, 12, 6, 10 으로 구성된 5칸이고,

arr3은 1~9까지로 구성된 9칸 짜리인데

 

arr2 = arr3 이 되면 

 

내 머릿속으로는 arr2가 담겨 있던 박스에 arr3이 들어가면서 일부 짤리고 

1,2,3,4,5 가 될 것 같았다. 

 

하지만 배열은 배열이 시작하는 위치(주소)만 기억하는 방식이라서 배열의 크기는 상관이 없다 

그냥 arr2가 있는 곳에 arr3이 생긴 거라고 보면 된다. 

그래서 아래와 같이 출력된다. 

이렇게 보인다...

아직 인간의 사고 방식을 벗어나지 못했다... 

 

[문자의 배열]

아래와 같이 문자의 배열도 가능하다. 

            string[] week = new string[] { "월", "화", "수", "목", "금", "토", "일" };

            foreach (string i in week) Console.WriteLine(i);

요일이 출력됐다

 

[강의 내용]

https://www.notion.so/2023-07-02-2331776a17af49cc85dae245fd31d27b

 

반응형