array에는 크게 두 가지가 있다.
1.
int arr1[5];
2.
int *arr2;
arr2 = (int*) malloc(sizeof(int)*5);
배열의 데이터가 1번은 스택에 저장되고 2번은 힙에 저장된다.
이건 1차원 배열에선 크게 상관이 없다.
1차원 배열에선 두 가지를 혼용하여 사용하여도 큰 상관은 없지만
2차원 이상 다차원 배열에선 문제가 된다.
2차원 배열을 보면
1.
int arr1[2][5];
2.
int **arr2;
arr2 = (int**) malloc(sizeof(int*) * 2);
arr2[0] = (int*) malloc(sizeof(int)*5);
arr2[1] = (int*) malloc(sizeof(int)*5);
or
int **arr2;
arr2 = (int**) malloc(sizeof(int*) * 2);
int brr0[5], brr1[5];
arr2[0] = brr0;
arr2[1] = brr1;
우선 type을 보면
1번에서 arr1은 int*형 type을 갖고
2번에서 arr2는 int**형 type을 갖는다.
저장되는 공간을 보면
1번 배열은 2*5 int형 데이터가 스택에 10개가 쫘르륵 배치된다.
2번 배열은 한 줄(5개)이 각각 다른 장소에 지정되고, arr은 int 5개가 저장되있는 각각의 장소를 가르킨다.
컴파일러 입장에서보면
1번은 컴파일 타임에 위치를 알 수 있고,
2번은 실행시간에야 위치를 알 수 있다.
(다음을 봐보자)
액세스 방식을 보면 (1, 3)액세스
1번에서 arr1[1][3]은 arr + 1 * 5 + 3의 값 같은 의미를 갖는다. = *( arr + 1 * 5 + 3 )
2번에선 arr2[1][3]은 arr[1] + 3과 같은 의미를 갖는다. = *( arr[1] + 3 )
우선 arr[1]주소로 가서 두번째 줄 값이 저장된 장소를 알아낸후 (int*)
5개의 값 중 3번째 값을 가져온다. *( arr[1] + 3)
다시 말하면
1번의 arr1은 바로 값이 있는 위치를 알고 있고 (int*)
2번의 arr2는 값이 있는 위치를 알고있는 그 위치를 알고 있는것이다.(int**)
중요한 다른 함수로 배열 값을 넘길 때를 보자.
1.
선언
void boo( int arr1[2][5] ) or void boo( int arr1[][5] )
호출
boo(arr1);
2.
선언
void foo(int **arr2)
호출
foo(arr2)
이런 식으로 선언, 호출을 해야한다.
1번에선 이 배열은 5개씩 묶음이 2개 있다 읽을 때 5개씩 띄어서 읽어라 라고 알려주기 위한 선언이고
2번에선 이 배열은 2차원 포인터 배열이니 읽을 때는 점프 두번해서 읽어라 라고 알려주기 위한 선언이다.
1번에선 점프하면 값을 읽을 수 있지만
2번에서 값을 읽으려면 점프 + 점프 해야 값을 읽을 수 있는 것이다.
결론
1.
int arr[i][j];
이런 2차원 배열은 int*형을 같는다.
도 arr의 자료형은 int* 이지만
1차원은 int*
2차원도 int *
3차원도 int *
4차원도 int *
2.
int **arr;
이런 다이나믹한 배열에선 배열 변수도 같은 차원을 같는다.
1차원은 int*
2차원은 int **
3차원은 int ***
4차원은 int ****
함수하나에서만 데이터를 사용한다면 큰 무리는 없지만,
다른 함수로 데이터를 넘기기 위해선 두 배열의 차이를 알아야한다.
'Program Language > C' 카테고리의 다른 글
[C] likely/unlikely macros (0) | 2012.12.14 |
---|---|
LNK2005 already defined in LNK1169: one or more multiply defined symbols found (0) | 2012.11.27 |
#ifdef #else #endif #elifdef (0) | 2012.08.09 |
printf debugging (0) | 2012.06.19 |
sizeof (0) | 2012.06.04 |
댓글