다차원 배열은 2차원 이상의 배열을 의미한다.


앞서 공부한 1차원 배열이 가로였다면, 2차원배열은 가로 세로, 3차원 배열은 가로 세로 높이 이다. 이렇게 쭈욱 있다. 하지만 실제로 자주 사용되는것은 1차원배열과 2차원배열이다.


int arr1[10];            // 길이가 10인 1차원 int형 배열

int arr2[5][6];         // 세로가 5, 가로가 6인  2차원 int형 배열

int arr3[3][4][5];    // 높이가 3, 세로가 4, 가로가 5인 3차원 int형 배열


2차원 배열의 선언


int arr1[3][4];        // 세로가 3, 가로가 4인 int형 2차원 배열


int arr2[2][6];       // 세로가 2, 가로가 6인 int형 2차원 배열


위 그림에서 배열요소 안에 삽입된 두 개의 숫자는 각각의 요소에 접근할 때 사용하게 되는 인덱스 값이다.


2차원 배열요소에 접근하는 방법은 쉽다.


arr[N-1][M-1]=20;                // 세로 N, 가로 M의 위치에 정수 20을 저장

printf("%d", arr[N-1][M-1]); // 세로 n, 가로 M의 위치에 저장된 값을 출력


ex)가구별 거주인원 입력받기

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
32
#include<stdio.h>
 
int main()
{
    int arr[4][2];
    int sum,i,j;
    
    /* 가구별 거주인원 입력 받기 */
    for(i=0;i<4;i++)
    {
        for(j=0;j<2;j++)
        {
            printf("%d층 %d호 인구수:",i+1,j+1);
            scanf("%d",&arr[i][j]);
        }
    }
    
    /* 층별 인구수 출력하기 */
    
    for(i=0;i<4;i++)
    {
        sum=0;
        for(j=0;j<2;j++)
        {
            sum += arr[i][j];
        }
        printf("%d층 총원:%d\n",i+1,sum);
    }
    
    return 0;
}
 

cs

출력결과

1 1 인구수:2

1 2 인구수:4

2 1 인구수:3

2 2 인구수:5

3 1 인구수:2

3 2 인구수:6

4 1 인구수:4

4 2 인구수:3

1 총원:6

2 총원:8

3 총원:8

4 총원:7


위 예제를 1차원 배열로 이용해서 만들어보자 ( practice 카테고리에 있음)


2차원 배열은 물리적으로도 2차원의 형태일까? 우리가 사용하고 있는 메모리의 구조는 2차원적 구조가 아니다. 이는 메모리의 주소 값을 통해서 알 수 있다. 


0x1001번지, 0x1002번지, 0x1003번지, 0x1004번지, 0x1005번지, 0x1006번지 . . . .


만약 2차원 구조였다면 메모리의 주소 값은 다음의 형태를 띠었을 것이다.


0x12-0x24번지, 0x12-0x25번지, 0x12-0x26번지, 0x12-0x27번지 . . . .

0x13-0x24번지, 0x13-0x25번지, 0x13-0x26번지, 0x13-0x27번지 . . . .

0x14-0x24번지, 0x14-0x25번지, 0x14-0x26번지, 0x14-0x27번지 . . . .


따라서 2차원배열도 메모리 상에는 1차원의 형태로 존재한다. 


ex)2차원배열의 주소값 출력하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
 
int main()
{
    int arr[3][2];
    int i,j;
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<2;j++)
        {
            printf("%p\n"&arr[i][j]);
        }
    }
    return 0;
}
 

cs

출력결과

0x7ffeefbff5f0

0x7ffeefbff5f4

0x7ffeefbff5f8

0x7ffeefbff5fc

0x7ffeefbff600

0x7ffeefbff604


이렇게 4바이트씩 차이나는 것을 알 수 있다.


2차원 배열 선언과 동시에 초기화하기

초기화 리스트 안에는 행 단위로 초기화할 값들을 별도의 중괄호로 명시해야 한다. 물론 모든 매열요소를 초기화해야 하는 것은 아니다. 

밑에 그림처럼 일부에 대해서 초기화할 수 있고, 비게 되는 공간은 0으로 초기화 된다.


위 그림에서 선언하고 있는 배열의 모든 행은 3개의 요소로 이뤄져 있다. 그런데 1행과 2행을 초기화 할 값이 각각 두 개와 한 개가 부족한데 이럴 경우 빈 영역은 0으로 초기화 된다.



위 그림과 같이 행 단위 중괄호 없이 초기화 리스트를 나열하면 1행 1열부터 시작해서 배열의 마지막 요소까지 순서대로 값이 초기화 되는데, 부족한 영역은 0으로 초기화 된다. 또 한, 이는 밑의 문장과 같다.


int arr[3][3]={1,2,3,4,5,6,7};


ex)배열 초기화 예

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<stdio.h>
 
int main()
{
    int i,j;
    
    /* 2차원 배열 초기화 예1 */
    int arr1[3][3]={
        {1,2,3},
        {4,5,6},
        {7,8,9}
    };
    
    /* 2차원 배열 초기화 예2 */
    int arr2[3][3]={
        {1},
        {4,5},
        {7,8,9}
    };
    
    /* 2차원 배열 초기화 예3 */
    int arr3[3][3]={1,2,3,4,5,6,7};
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%d",arr1[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%d",arr2[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%d",arr3[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    
    return 0;
}
 

cs

출력결과

123

456

789


100

450

789


123

456

700

1차원 배열은 배열의 크기를 정해주지 않으면 컴파일러가 알아서 결정을 하였다.

arr1[]={1,2,3};     // arr[3];


2차원 배열은 둘 중 하나는 무조껀 알려줘야 에러메시지를 띄우지 않는다. 그 중에 가로의 길이를 가르쳐 주기로 한다.

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

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


3차원 배열은 흔히 사용되는 배열이 아니다.

2차원 배열을 이해하고 있다면 3차원 배열도 쉽다.


int arr[2][3][4];     // 높이2, 세로3, 가로 4인 int형 3차원 배열


위의 문장은 세로가 3, 가로가4인 2차원배열 2개가 있는 것과 같다.


ex)3차원 배열의 접근과 선언

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<stdio.h>
 
int main()
{
    int mean=0,i,j;
    int record[3][3][2]={
    {
        {70,80},     // A학급 학생 1의 성적
        {94,90},     // A학급 학생 2의 성적
        {70,85}      // A학급 학생 3의 성적
    },
    {
        {83,90},     // B학급 학생 1의 성적
        {94,87},     // B학급 학생 2의 성적
        {76,85}      // B학급 학생 3의 성적
    },
    {
        {68,90},     // C학급 학생 1의 성적
        {99,96},     // C학급 학생 2의 성적
        {78,87}      // C학급 학생 3의 성적
    }
 };
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<2;j++)
        {
            mean += record[0][i][j];
        }
    }
    printf("A 학급 전체 평균 : %g \n",(double)mean/6);
    mean=0;
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<2;j++)
        {
            mean += record[1][i][j];
        }
    }
    printf("B 학급 전체 평균 : %g \n",(double)mean/6);
    mean=0;
    
    for(i=0;i<3;i++)
    {
        for(j=0;j<2;j++)
        {
            mean += record[2][i][j];
        }
    }
    printf("C 학급 전체 평균 : %g \n",(double)mean/6);
    
    return 0;
}
 

cs

출력결과

A 학급 전체 평균 : 81.5 

B 학급 전체 평균 : 85.8333 

C 학급 전체 평균 : 86.3333 


3차원 배열은 여러개의 2차원배열이 모여있는 형태로 이해하는 것이 더 합리적이다.


'programming > C' 카테고리의 다른 글

C // 2차원 배열이름의 포인터 형  (0) 2017.12.24
C // 포인터의 포인터  (0) 2017.12.23
C // 포인터와 함수  (0) 2017.12.21
C // 포인터와 배열  (0) 2017.12.20
C // 포인터  (0) 2017.12.19

+ Recent posts