-
C언어 다차원 배열과 포인터의 관계Programming/C 2016. 5. 2. 20:55
다차원 배열과 포인터의 관계
2차원 배열이름의 포인터 형
#include <stdio.h> int main(void) { int arr2d[3][3]; printf("%d \n", arr2d); printf("%d \n", arr2d[0]); printf("%d \n\n", &arr2d[0][0]); printf("%d \n", arr2d[1]); printf("%d \n\n", &arr2d[1][0]); printf("%d \n", arr2d[2]); printf("%d \n", &arr2d[2][0]); printf("sizeof(arr2d): %d \n", sizeof(arr2d)); printf("sizeof(arr2d[0]): %d \n", sizeof(arr2d[0])); printf("sizeof(arr2d[1]): %d \n", sizeof(arr2d[1])); printf("sizeof(arr2d[2]): %d \n", sizeof(arr2d[2])); return 0; }
1386507056 1386507056 1386507056 1386507068 1386507068 1386507080 1386507080 sizeof(arr2d): 36 sizeof(arr2d[0]): 12 sizeof(arr2d[1]): 12 sizeof(arr2d[2]): 12
arr2d는 첫 번째 요소를 가리키면서 배열 전체를 의미하지만 arr2d[0]은 첫 번째 요소를 가리키되 1행만을 의미한다. 그래서 sizeof 연산의 결과가 다른 것이다. 즉, arr2d와 arr2d[0]은 서로 다른 것이다.
가리키는 대상이 int형 변수이면서 포인터 연산 시 sizeof(int)x4의 크기 단위로 증가 및 감소하는 포인터 변수 ptr은 다음과 같이 선언
int (*ptr) [4];
2차원 배열이름의 특성과 주의사항
'배열 포인터'와 '포인터 배열'
int * whoA [4]; // 포인터 배열 int (*whoB) [4]; // 배열 포인터
#include <stdio.h> int main(void) { int num1 = 10, num2 = 20, num3 = 30, num4 = 40; int arr2d[2][4] = {1, 2, 3, 4, 5, 6, 7, 8}; int i, j; int * whoA[4] = {&num1, &num2, &num3, &num4}; // 포인터 배열 int (*whoB)[4] = arr2d; // 배열 포인터 printf("%d %d %d %d \n", *whoA[0], *whoA[1], *whoA[2], *whoA[3]); for(i=0; i<2; i++) { for(j=0; j<4; j++) printf("%d ", whoB[i][j]); printf("\n"); } return 0; }
10 20 30 40 1 2 3 4 5 6 7 8
whoA는 int형 포인터 변수로 이뤄진 int형 포인터 배열,
whoB는 가로길이가 4인 int형 2차원 배열을 가리키는 용도의 포인터 변수#include <stdio.h> void ShowArr2DStyle(int (*arr)[4], int column) // 배열요소 전체출력 { int i, j; for(i=0; i<column; i++) { for(j=0; j<4; j++) printf("%d ", arr[i][j]); printf("\n"); } printf("\n"); } int Sum2DArr(int arr[][4], int column) // 배열요소의 합 반환 { int i, j, sum = 0; for(i=0; i<column; i++) for(j=0; j<4; j++) sum += arr[i][j]; return sum; } int main(void) { int arr1[2][4] = {1, 2, 3, 4, 5, 6, 7, 8}; int arr2[3][4] = {1, 1, 1, 1, 3, 3, 3, 3, 5, 5, 5, 5}; ShowArr2DStyle(arr1, sizeof(arr1)/sizeof(arr1[0])); ShowArr2DStyle(arr2, sizeof(arr2)/sizeof(arr2[0])); printf("arr1의 합: %d \n", Sum2DArr(arr1, sizeof(arr1)/sizeof(arr1[0]))); printf("arr2의 합: %d \n", Sum2DArr(arr2, sizeof(arr2)/sizeof(arr2[0]))); return 0; }
1 2 3 4 5 6 7 8 1 1 1 1 3 3 3 3 5 5 5 5 arr1의 합: 36 arr2의 합: 36
sizof(arr1)과 sizeof(arr2)의 반환 값은 배열의 전체 크기이고, sizof(arr1[0])와 sizeof(arr2[0])의 반환 값은 배열의 가로 크기 이므로 나누면 배열의 세로 길이가 나오게 된다.
sizeof(arr1) / sizeof(arr1[0]) sizeof(arr2) / sizeof(arr2[0])
2차원 배열에서도 arr[i]와 *(arr+i)는 같다.
배열과 포인터의 관계에서 다음식이 성립했는데 다차원 배열에서도 성립이 가능하다.
arr[i] == *(arr+i) // arr[i]는 *(arr+i)와 같다.
2차원 배열이 다음과 같이 있다. 그리고 인덱스 [2][1]에 있는 값을 4로 변경하기 위해선 2번째 줄의 문장을 실행해야 한다.
arr[3][2] = { {1, 2}, {3, 4}, {5, 6} }; arr[2][1] = 4;
이는 다음 문장들로 대신할 수 있다.
(*(arr+2))[1] = 4; *(arr[2]+1) = 4; *(*(arr+2)+1) = 4;
첫 번째 식은 arr[2]를 (arr+2)로 바꿈으로써 구할 수 있다. 그리고 두 번째 식은 치환이 필요하다. arr[2][1]에서 arr[2]를 A로 치환하면 다음과 같아 변환이 된다.
A[1] = 4; → *(A+1) = 4;
여기서 A를 원래대로 되돌리면 (arr[2]+1)=4가 된다. 마지막 식은 두 번째 식에서 arr[2]를 *(arr+2)로 바꾸면 가능하다.#include <stdio.h> int main(void) { int a[3][2] = {{1, 2}, {3, 4}, {5, 6}}; printf("a[0]: %p \n", a[0]); printf("*(a+0): %p \n", *(a+0)); printf("a[1]: %p \n", a[1]); printf("*(a+1): %p \n", *(a+1)); printf("a[2]: %p \n", a[2]); printf("*(a+2): %p \n", *(a+2)); printf("%d, %d \n", a[2][1], (*(a+2))[1]); printf("%d, %d \n", a[2][1], *(a[2]+1)); printf("%d, %d \n", a[2][1], *(*(a+2)+1)); }
a[0]: 0x7fff54952b40 *(a+0): 0x7fff54952b40 a[1]: 0x7fff54952b48 *(a+1): 0x7fff54952b48 a[2]: 0x7fff54952b50 *(a+2): 0x7fff54952b50 6, 6 6, 6 6, 6
성립을 확인
#include <stdio.h> int main(void) { int * arr1[5]; int * arr2[3][5]; int ** ptr1 = arr1; int * (*ptr2)[5] = arr2; }
'Programming > C' 카테고리의 다른 글
도전 프로그래밍3 (0) 2016.05.02 C언어 함수 포인터와 void 포인터 (0) 2016.05.02 C언어 포인터의 포인터 (0) 2016.05.02 C언어 다차원 배열 (0) 2016.05.02 C언어 포인터 대상의 const 선언 (0) 2016.05.02