for 중첩 루프 – C언어 강의 13

for 중첩 루프

for 중첩 루프는 for 루프 안에 또 다른 for 루프가 돌아가게 하는 제어입니다. 행과 열이 있는 2차원 행렬을 만들 수 있습니다. 여러가지 응용을 할 수 있는데 이 포스팅에서는 기본적인 예제들로 알아보겠습니다.

중첩루프 예제

사각형을 출력하는게 중첩루프의 기본입니다. printf 로 숫자를 출력해도 좋고 * 별모양도 좋습니다. for 문 안에 int i 는 block 의 scope가 다르기 때문에 똑같이 사용할 수 있습니다만, 보통은 중첩된 코드에 j를 사용합니다. 예시로 동일하게 i를 넣었습니다. 중첩된 둘은 scope가 다릅니다.

#include <stdio.h>

int main(void) 
{
    for (int i = 0; i < 5; i++)
    {
        for (int i = 0; i < 5; i++)
        {
            printf("1 ");
        }
        printf("\n");
    }

    return 0; 
}
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 

무언가 숫자를 출력해 봅니다. 내부의 루프가 다섯번 반복되고 다시 외부의 루프가 실행되고 이런식으로 내부와 외부를 바꿔가며 실행됩니다. 현재 어느 라인에 있느냐는 제어적으로나 scope 적으로나 중요합니다. 코드가 위치한 라인에 따라 변수 값이 달라지는 것을 파악하고 있어야 합니다. 그냥 눈으로 쫓는 일은 어렵기 때문에 복잡한 코드는 debug 도구의 도움을 받는게 좋습니다.

#include <stdio.h>

int main(void) 
{

    for (int i = 0; i < 5; i++)
    {
        for (int j = 1; j <= 5; j++)
        {
            printf("%2d ",j);
        }
        printf("\n");
    }
    return 0; 
}
 1  2  3  4  5 
 1  2  3  4  5 
 1  2  3  4  5 
 1  2  3  4  5 
 1  2  3  4  5 

구구단 출력 코드를 처음에 해보면 도움이 됩니다. 2단을 다 출력하고 다음 3단, 4단 … 9단까지 출력하는 순서가 구구단 암기와 같습니다. 컴퓨터도 사람하고 비슷하게 생각할 수 있습니다.

#include <stdio.h>

int main(void) 
{
    for (int i = 2; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            printf("(%dx%d=%2d) ",i, j, i*j);
        }
        printf("\n");
    }
    return 0; 
}
(2x1= 2) (2x2= 4) (2x3= 6) (2x4= 8) (2x5=10) (2x6=12) (2x7=14) (2x8=16) (2x9=18) 
(3x1= 3) (3x2= 6) (3x3= 9) (3x4=12) (3x5=15) (3x6=18) (3x7=21) (3x8=24) (3x9=27) 
(4x1= 4) (4x2= 8) (4x3=12) (4x4=16) (4x5=20) (4x6=24) (4x7=28) (4x8=32) (4x9=36) 
(5x1= 5) (5x2=10) (5x3=15) (5x4=20) (5x5=25) (5x6=30) (5x7=35) (5x8=40) (5x9=45) 
(6x1= 6) (6x2=12) (6x3=18) (6x4=24) (6x5=30) (6x6=36) (6x7=42) (6x8=48) (6x9=54) 
(7x1= 7) (7x2=14) (7x3=21) (7x4=28) (7x5=35) (7x6=42) (7x7=49) (7x8=56) (7x9=63) 
(8x1= 8) (8x2=16) (8x3=24) (8x4=32) (8x5=40) (8x6=48) (8x7=56) (8x8=64) (8x9=72) 
(9x1= 9) (9x2=18) (9x3=27) (9x4=36) (9x5=45) (9x6=54) (9x7=63) (9x8=72) (9x9=81) 

중첩루프로 도형그리기

중첩해서 루프를 하면 사각형이나 삼각형을 만들 수 있는데 실습을 해보면 알고리즘을 이해하는데 도움이 됩니다. 2차원 배열은 면을 의미하므로 2D 컴퓨터 게임에서는 게임의 맵이나 보드 같은 것을 만들 때 많이 사용하는 방법입니다.

#include <stdio.h>

int main(void) 
{
    int number = 1;

    for (int i = 1; i <= 5; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            printf("[%d]",j);
        }
        printf("\n");
    }
    printf("------------------\n");
    for (int i = 1; i <= 5; i++)
    {
        for (int j = 5; j >= i; j--)
        {
            printf("[%d]",j);
        }
        printf("\n");
    }
    printf("------------------\n");

    for (int i = 1; i <= 5; i++)
    {
        for (int j = 5; j >= i; j--)
        {
            printf("   ",j);
        }
        for (int j = 1; j <= i; j++)
        {
            printf("[%d]",j);
        }
        printf(" | ");
        for (int j = 1; j <= i; j++)
        {
            printf("[%d]",j);
        }
        printf("\n");
    }
    printf("------------------\n");

    return 0; 
}
[1]
[1][2]
[1][2][3]
[1][2][3][4]
[1][2][3][4][5]
------------------
[5][4][3][2][1]
[5][4][3][2]
[5][4][3]
[5][4]
[5]
------------------
               [1] | [1]
            [1][2] | [1][2]
         [1][2][3] | [1][2][3]
      [1][2][3][4] | [1][2][3][4]
   [1][2][3][4][5] | [1][2][3][4][5]
------------------

중첩문으로 2차원 배열을 초기화 시킬 수 있습니다. 외부 for는 행, 내부 for는 열이라 생각하면 이해가 쉽습니다.

#include <stdio.h>

int main(void) 
{
    const int SIZE = 5;

    int board[SIZE][SIZE];

    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            printf("(%d,%d) ", i, j);
            board[i][j] = i*j;
        }
        printf("\n");
    }

    printf("-----------------------------\n");

    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            printf("[%2d]", board[i][j]);
        }
        printf("\n");
    }

    printf("-----------------------------\n");

    return 0; 
}
(0,0) (0,1) (0,2) (0,3) (0,4) 
(1,0) (1,1) (1,2) (1,3) (1,4) 
(2,0) (2,1) (2,2) (2,3) (2,4) 
(3,0) (3,1) (3,2) (3,3) (3,4) 
(4,0) (4,1) (4,2) (4,3) (4,4) 
-----------------------------
[ 0] [ 0] [ 0] [ 0] [ 0] 
[ 0] [ 1] [ 2] [ 3] [ 4] 
[ 0] [ 2] [ 4] [ 6] [ 8] 
[ 0] [ 3] [ 6] [ 9] [12] 
[ 0] [ 4] [ 8] [12] [16] 
-----------------------------

3차원 배열 루프

여기서 3차원 배열까지 다룰 것 까진 없지만 for 루프 하나에 차원 하나가 늘어납니다.

#include <stdio.h>

int main(void) 
{
    const int SIZE = 3;

    int board[SIZE][SIZE][SIZE];

    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            for(int k=0; k < SIZE; k++)
            {
                printf("(%d,%d,%d)", i, j, k);
                board[i][j][k] = i*j*k;
            }
            printf(" | ");
        }
        printf("\n");
    }

    printf("-----------------------------------------------------------------------\n");

    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            for(int k=0; k < SIZE; k++)
            {
                printf("[%2d]", board[i][j][k]);
            }
            printf(" | ");
        }
        printf("\n");
    }

    printf("-----------------------------------------------------------------------\n");

    return 0; 
}
(0,0,0)(0,0,1)(0,0,2) | (0,1,0)(0,1,1)(0,1,2) | (0,2,0)(0,2,1)(0,2,2) | 
(1,0,0)(1,0,1)(1,0,2) | (1,1,0)(1,1,1)(1,1,2) | (1,2,0)(1,2,1)(1,2,2) | 
(2,0,0)(2,0,1)(2,0,2) | (2,1,0)(2,1,1)(2,1,2) | (2,2,0)(2,2,1)(2,2,2) | 
-----------------------------------------------------------------------
[ 0][ 0][ 0] | [ 0][ 0][ 0] | [ 0][ 0][ 0] | 
[ 0][ 0][ 0] | [ 0][ 1][ 2] | [ 0][ 2][ 4] | 
[ 0][ 0][ 0] | [ 0][ 2][ 4] | [ 0][ 4][ 8] | 
-----------------------------------------------------------------------

요약

for 의 중첩 루프를 응용하여 다양한 알고리즘을 만들 수 있습니다. 머리로 이해하려고 하면 힘든데 실습을 하다보면 어렵지 않습니다. GDB나 비주얼 스튜디오의 디버거를 사용한다면 값의 확인이 좀 더 수월할 겁니다.

참고문서

Nested Loops in C with Examples – GeeksforGeeks

Leave a Comment