2016년 2월 27일 토요일

C언어 2차원 배열 구조(array 2 dim)


C언어는 배열 선언 방법은 아래와 같습니다.

int A[6];

                 

위와 같이 선언을 하게되면 A라는 변수에 6개의 메모리가 할당이 됩니다.

그리고 6개의 메모리가 순차적으로 연속적인 메모리 공간의 주소에 존재하게 됩니다.
또한 C 언어에서는 index가 0부터 증가하기 때문에 A[0] ~ A[5]까지 메모리 주소 공간을 사용할 수 있습니다.
물론 A[6]을 사용한다고 컴파일 오류가 발생하지는 않습니다. 동작중에 C언어는 index검사를 하지 않기 때문입니다. 이러한 이유로 디버깅이 어려울 때도 있지만 불필요한 검사는 개발자 자신의 몫으로 둠으로서 속도의 향상을 대가로 받습니다.

만야 2차원 배열이라면 어떻게 될까요?

int B[2][4];

위와 같이 정의하면 아래와 같이 메모리가 할당이 된다고 예상 할 것입니다.

           
           

하지만 C언어에 있어서 이것은 환상에 지나지 않습니다. C 언어의 경우 B[2][4] 2*4=8개의 int 형 메모리 주소 공간을 연속적으로 할당받게 됩니다. 결국 언어가 받아들이는 메모리 소모적인 측면에서 B[2][4] 나 B[4][2] 이나 동일 합니다.

[0][0] [0][1] [0][2] [0][3] [1][0] [1][1] [1][2] [1][3]

위와 같은 메모리 형태로 되어있으며 아래와 같이 되어있다고 생각해도 동일합니다.
[0][0] [0][1] [1][0] [1][1] [2][0] [2][1] [3][0] [3][1]

즉 B[1][2] 에넣은값을 B[3][0]에 넣은 값이 동일하지 않을까라는 의문에서 시작해보면 아래와 같은 코드를 생각해 볼 수 있습니다.
하지만 결과를 보면 100으로 넣은값이 0으로 나오는것을 알 수 있습니다.
이렇게 되는 이유는 C 컴파일러가 앞쪽 인덱스가 증가할때 15,16 line B[0][1]:0 0x8049884
, B[1][0]:0 0x8049890 0x84->0x90 으로 건너 뛰는것을 알 수 있습니다. 즉 array 차원 정보에는 인덱스 증가시 몇 바이트를 건너 뛰어야 하는 정보가 있어서 그렇습니다.


Cpasted just now: 
#include <stdio.h>
int B[2][4];

main()
{
    int i,j;
    printf("B[1][2]:%d\n",B[1][2]);
    B[1][2] = 100;
    printf("B[1][2]<=:%d\n",B[1][2]);
    printf("B[3][0]:%d\n",B[3][0]);

    printf("---\n");
    for(i=0;i<2;i++){
        for(j=0;j<4;j++){
            printf("B[%d][%d]:%d %p\n",i,j,B[i][j],&B[i][j]);
        }
    }
    printf("---\n");
    for(i=0;i<4;i++){
        for(j=0;j<2;j++){
            printf("B[%d][%d]:%d %p\n",i,j,B[i][j],&B[i][j]);
        }
    }

    return 0;
}


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
B[1][2]:0
B[1][2]<=:100
B[3][0]:0
---
B[0][0]:0 0x8049880
B[0][1]:0 0x8049884
B[0][2]:0 0x8049888
B[0][3]:0 0x804988c
B[1][0]:0 0x8049890
B[1][1]:0 0x8049894
B[1][2]:100 0x8049898
B[1][3]:0 0x804989c
---
B[0][0]:0 0x8049880
B[0][1]:0 0x8049884
B[1][0]:0 0x8049890
B[1][1]:0 0x8049894
B[2][0]:0 0x80498a0
B[2][1]:0 0x80498a4
B[3][0]:0 0x80498b0
B[3][1]:0 0x80498b4



아래 정보를 보면 메모리상 4byte씩 연속되어 있음을 확인할 수 있습니다.
B[0][0]:0 0x8049880
B[0][1]:0 0x8049884
B[0][2]:0 0x8049888
B[0][3]:0 0x804988c
B[1][0]:0 0x8049890
B[1][1]:0 0x8049894
B[1][2]:100 0x8049898
B[1][3]:0 0x804989c

따라서 배열을 int B[2][4]; 선언을 하였으면 메모리 배치가 연속되어 있다고 하더라도 차원 인자는 혼용해서 사용하면 안됩니다. 하지만 포인터를 이용해서는 사용이 가능합니다.


Cpasted 1 second ago: 
#include <stdio.h>
int B[2][4];
int *pB;

main()
{
    int i,j;
    printf("B[1][2]:%d\n",B[1][2]);
    B[1][2] = 100;
    printf("B[1][2]<=:%d\n",B[1][2]);
    printf("B[3][0]:%d\n",B[3][0]);
    printf("---\n");

    pB=(int *)&B;
    for(i=0;i<2;i++){
        for(j=0;j<4;j++){
            printf("pB[%d*4+%d]:%d %p\n",i,j,pB[i*4+j],&pB[i*4+j]);
        }
    }
    printf("---\n");
    for(i=0;i<4;i++){
        for(j=0;j<2;j++){
            printf("pB[%d*2+%d]:%d %p\n",i,j,pB[i*2+j],&pB[i*2+j]);
        }
    }

    return 0;
}


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
B[1][2]:0
B[1][2]<=:100
B[3][0]:0
---
pB[0*4+0]:0 0x8049880
pB[0*4+1]:0 0x8049884
pB[0*4+2]:0 0x8049888
pB[0*4+3]:0 0x804988c
pB[1*4+0]:0 0x8049890
pB[1*4+1]:0 0x8049894
pB[1*4+2]:100 0x8049898
pB[1*4+3]:0 0x804989c
---
pB[0*2+0]:0 0x8049880
pB[0*2+1]:0 0x8049884
pB[1*2+0]:0 0x8049888
pB[1*2+1]:0 0x804988c
pB[2*2+0]:0 0x8049890
pB[2*2+1]:0 0x8049894
pB[3*2+0]:100 0x8049898
pB[3*2+1]:0 0x804989c


댓글 없음:

댓글 쓰기