Unity_사전캠프

[사전캠프 8일차] 이중 반복문, 배열 최소최대

티백고래 2025. 3. 26. 18:06

1. 오늘 학습 키워드

우선 이중 반복문을 이용하여 구구단을 만들어볼 것이다.

그리고, 배열속에서 최소값과 최대값을 찾는 코드도 작성해볼 예정이다.

2. 오늘 학습 한 내용을 나만의 언어로 정리하기

2-1. 이중반복문

조건 1. 이중반복문의 작성

 

이중반복문은, 말 그대로 반복문 안에 또 다른 반복문이 있는 것이다. 

for 반복문의 이중반복문을 예시로 들자면, 

 

for(1번 반복)

{

    for(2번)

    {

        실행코드1

    }

    실행코드2

}

이런 구성이 된다. 

순서를 설명하자면,

가장 바깥의 for문 1번을 1회 반복하기 전 안쪽에 있는 for문 2번의 의 [실행코드 1]이 먼저 한 차례 전부 반복한 다음  실행코드 2가 실행되고, 다음 반복단계에서 다시 [실행코드 1]이 for문 2번의 조건을 충족시킬 때까지 재차 반복된다.

 

이 구성을 가장 잘 볼 수 있는 것은, 구구단이다.

 

코드1

더보기

// x * y에서 y가 1부터 9까지 쓰면 다음 단으로 넘어가는 방식

// 2*1, 2*2, 2*3

int x;
int y;  //x와 y가 정수임을 미리 선언

 

for (x = 2; x <= 9; x++)
{

    for (y = 1; y <= 9; y++) //바깥의 반복문이 1회 실행될 때마다 반복됨.
    {
        Console.WriteLine(x + "×" + y + "=" + x * y);  //반복될 때마다 출력
    }

    Console.WriteLine(); //한 번의 반복이 끝나면, 다음 반복과 구분하기 위한 공백(2단과 3단을 나눔)
}

너무 길어서 잘랐습니다. 9*9까지 정상적으로 출력됩니다.

 

// x * y에서 2부터 9에 같은 수를 곱하고 다음에는 하나 더 큰 수를 곱하는 것으로 넘어가는 방식

//2*1, 3*1, 4*1…형태이다.

 

for (y = 1; y <= 9; y++)
{
    
    for (x = 2; x <= 9; x++)
    {
        Console.WriteLine(x + "×" + y + "=" + x*y);
    }

    Console.WriteLine();
}

 

더 많이 반복되어야 하는 부분이 안쪽, 그다음 새로 반복해야 하는 부분을 바깥쪽으로 넣는다고 생각하면 될 것 같다.

일종의 깜지나 빽빽이를 쓴다고 생각하면 이해가 쉬울 수도 있겠다.

가장 바깥의 반복문은 노트를 넘긴다는 행위이고,

안쪽의 반복문은 같은 내용을 반복해서 작성한다는 행위라고 생각하면 이해가 쉬울 것이다.

 

2-2. 배열에서 최소값 최대값 구하기

조건 1: 미리 설정한 값 중에서 최소값 최대값 판정하는 기능 만들기.

조건 2: 입력한 값들 중에서 최소값 최대값 판정하는 기능 만들기

조건 3: 입력값이 전부 숫자로 입력될 때까지 다시 작성할 수 있도록 하기

 

배열은 int나 string [ ] 의 형태로 각 방을 만들어주는 것임을 지난 시간에 배웠다.

그럼 그 안에서 반복적으로 값을 확인하는 것으로 최대값과 최소값을 구해볼 수 있을까? 를 목표로 한 번 구현해보도록 할 것이다.

 

코드 2

더보기

int[ ] num = { 10, 20, 30, 40, 50 }; //배열 속에 들어갈 수를 10, 20, 30, 40, 50으로 설정한다.
int min = num[0]; //왜 둘다 0으로 잡나요?
int max = num[0]; //아래 for문에서 0부터 1씩 올려가며 크기 비교를 할 것이기 때문입니다.


for (int i = 0; i < num.Length; i++)

//num.Length는 뭔가요? : num은 배열의 이름. 즉 배열의 길이를 구하는 것.

//num이라는 이름의 배열은 방이 5개이므로 배열의 길이는 5이다.

//위 상황에서 우리는 배열의 크기가 0부터 4까지 있는 것을 알고 있으므로, i<5 로 쓰거나 i<=4로 써도 무관하다.

//하지만 .Length를 사용할 경우, 이후 배열의 크기가 커지거나 작아졌을 때 일일히 변경하지 않아도 된다.

{
    if (num[i] < min) //num [i]에 들어간 숫자가 min에 들어간 수보다 작다면,
    {
        min = num[i]; //min 값은 num [i]로 재설정된다.
    }
    if (num[i] > max) //num [i]에 들어간 숫자가 max에 들어간 수보다 크다면,
    {
        max=num[i]; //max 값은  num [i]로 재설정된다.
    }
}

Console.WriteLine(min); //최소값 먼저
Console.WriteLine(max); // 그다음 최대값 출력

실행 결과

 

미리 넣어둔 데이터에서 최소값과 최대값을 구하는 코드는 생각보다 간결하다! (주석이 많아서 길어 보일 뿐이다.)

그럼, 미리 넣어둔 데이터가 아니라, 외부에서 임의의 수를 넣어서 그 안에서 비교를 하는 것도 가능할까?

배열 속에 입력한 데이터가 들어갈 수 있도록 한다면 가능할 것 같다.

 

코드 2-2

더보기

//지문 출력용 Console.WriteLine은 흐리게 작성했다.

Console.WriteLine("다섯 개의 수를 입력해주세요.");

Console.WriteLine("첫 번째 수를 입력해주세요.");
string ns0 = Console.ReadLine();
int n0;
Console.WriteLine("두 번째 수를 입력해주세요.");
string ns1 = Console.ReadLine();
int n1;
Console.WriteLine("세 번째 수를 입력해주세요.");
string ns2 = Console.ReadLine();
int n2;
Console.WriteLine("네 번째 수를 입력해주세요.");
string ns3 = Console.ReadLine();
int n3;
Console.WriteLine("다섯 번째 수를 입력해주세요.");
string ns4 = Console.ReadLine();
int n4;

bool nb0 = int.TryParse(ns0, out n0); //0번부터 순서에 맞춰서 입력
bool nb1 = int.TryParse(ns1, out n1);
bool nb2 = int.TryParse(ns2, out n2);
bool nb3 = int.TryParse(ns3, out n3);
bool nb4 = int.TryParse(ns4, out n4);

//여기까지 입력한 값을 정수 n0~n4까지 지정


if(nb0 && nb1 && nb2 && nb3 && nb4) //입력된 수가 모두 정수인지 확인
{
    Console.WriteLine("입력한 수: [" + n0+ " / " + n1 + " / " + n2 + " / " + n3 + " / " + n4 + " ]");
    int[ ] num = { n0, n1, n2, n3, n4 }; //배열 안에 들어가는 수를 입력값인 n0부터 n4까지로 작성
    int min = num[0];
    int max = num[0];
    for (int i = 0; i < num.Length; i++)
    {
        if (num[i] < min)
        {
            min = num[i];
        }
        if (num[i] > max)
        {
            max = num[i];
        } //코드 2에서 작성한 최소 최대값 구하는 코드와 동일
    }

    Console.WriteLine("최소값: " + min);
    Console.WriteLine("최대값: " + max);

}
else //입력값 중 하나라도 숫자가 아닐 경우 출력
{
    Console.WriteLine("데이터 중 숫자가 아닌 것이 있습니다.");
}

전부 정수로 입력했을 때

코드 2-2는 한 번이라도 잘못된 데이터를 입력하면 숫자가 아닌 것이 있다고 표기하고 종료하는 코드이지만, 입력한 5개의 값중 최소값과 최대값을 어렵지 않게 찾아낼 수 있다.

형변환 식만 따로 빼서, do-while 반복문을 이용한다면 잘못된 데이터를 입력했을 때 바로 새로운 값을 입력하여 계산하도록 만들 수도 있을 것 같다.

 

코드 2-3

더보기

Console.WriteLine("다섯 개의 수를 입력해주세요.");
Console.WriteLine("첫 번째 수를 입력해주세요.");
string ns0 = Console.ReadLine();
int n0;
bool nb0 = int.TryParse(ns0, out n0);

//우선 첫 입력에 입력된 ns0값이 정수 n0으로 변화하는지 확인
do
{
    if (nb0 == false) //입력한 값이 다시 false(즉, 정수가 아니라면) 이쪽으로.
    {
        Console.WriteLine("숫자를 입력해주세요.");
        ns0 = Console.ReadLine();     
        nb0 = int.TryParse(ns0, out n0); //입력한 값이 다시 정수로 변환될 수 있는지 확인한다.
    }
    else
    {
        Console.WriteLine();
    }
} while (!nb0);

//첫 nb0의 값이 true인 경우, 해당반복문은 이어서 공백만 출력하고 지나간다.
//이하 ns4번까지 코드 반복.

Console.WriteLine("두 번째 수를 입력해주세요.");
string ns1 = Console.ReadLine();
int n1;
bool nb1 = int.TryParse(ns1, out n1);

do
{
    if (nb1 == false)
    {
        Console.WriteLine("숫자를 입력해주세요.");
        ns1 = Console.ReadLine();
        nb1 = int.TryParse(ns1, out n1);
    }
    else
    {
        Console.WriteLine();
    }
} while (!nb1);

 

(중략)

//위에서 이미 모든 입력값이 정수임이 확인되었으므로, if문으로 재차 확인할 필요 없음.

//이하는 동일한 최소최대값을 구하는 코드
Console.WriteLine("입력한 수: [" + n0+ " / " + n1 + " / " + n2 + " / " + n3 + " / " + n4 + " ]");
int[] num = { n0, n1, n2, n3, n4 };
int min = num[0];
int max = num[0];
for (int i = 0; i < num.Length; i++)
{
    if (num[i] < min)
    {
        min = num[i];
    }
    if (num[i] > max)
    {
        max = num[i];
    }
}

Console.WriteLine("최소값: " + min);
Console.WriteLine("최대값: " + max);

음수도 정수이므로, 음수를 넣어도 문제없이 작동한다.

와! 드디어 입력한 값을 어떻게 넣든, 전부 숫자를 넣을 때까지 종료되지 않는 프로그램이 되었다.

또한, 입력한 값이 전부 숫자가 되면 입력된 값들 사이에서 최소값과 최대값을 어렵지 않게 찾아내는 것을 확인했다.

반복문, 조건문, 배열이 적절하게 쓰인 결과값이다.

이렇게 코드의 역할과 구성을 익히면, 원하는 기능으로 어렵지 않게 수정할 수 있음을 알 수 있다.

3. 학습하며 겪었던 문제점 & 에러

 - 문제&에러에 대한 정의

이중 반복문에서, 내가 원하는 대로 2×1, 2×2가 되지 않고 점점 숫자가 이상하게 불어나는 결과를 보았다.

계산식을 안밖으로 넣어두니 가장 바깥에 있는 x++가 이상하게 계산되었던 모양이다.

 - 내가 한 시도

우선 출력코드의 위치를 옮겼다.(Console.WriteLine(x+"×"+y+"="+x*y);)

처음엔 코드를 안과 밖에 두개를 설치했는데, 하나를 지워보았고, 그 남은 코드를 옮겨봤더니 해결되었다.

다행히 어려운 문제는 아니었다.

 - 해결 방법/새롭게 알게 된 점

이중반복문의 구조 자체를 파악하는데 도움이 되었다. 처음에는 이중반복문을 써야한다는 것만 알고, 구조를 정확하게 알지 못해서 문제를 해결하지 못했는데, 출력 코드를 옮겨가며 나오는 데이터를 확인하는 것으로 이중반복문이 어떻게 작동하는지까지 알 수 있었다.

4. 내일 학습 할 것은 무엇인지

내일은...행맨으로 만들어볼 예정이다. 

아쉽게도 그림을 하나하나 그려주는 건 아니고, 일정 횟수 안에 단어를 맞추는 게임이라는 방식 안에서 만들어볼 예정이다.

잘 되면 숫자야구까지 해볼 생각이지만... (가능할지는 모르곘다.)