2차원 배열의 포인터식 접근 (주소, 값의 표현)
1차원 배열에서 arr[i] 는 값을 의미했다. 포인터와 1차원 배열
2차원 배열이 1차원 배열과 다르다는 것을 이해할 때 가장 중요한 것은,
2차원 배열에서 arr[i] (== *(arr + i)) 는 값이 아닌 주소라는 점이다.
1차원 배열에서의 것과 다르기 때문에 헷갈릴 수 있어서 중요하다.
2차원 배열은 '열' 의 정보 뿐 아니라 '행' 의 정보도 필요하다.
arr[i]는 'i열' 이라는 정보만 담고 있기 때문에 i열의 시작 주소를 나타내게 된다.
int arr[2][3] = {10, 20, 30, 40, 50, 60};
printf("%x %x %x %x %x", arr[0], arr[0] + 0, *(arr + 0), *(arr + 0) + 0, &arr[0][0]);
// 43ffa50 43ffa50 43ffa50 43ffa50 43ffa50
위의 코드를 보면 arr[0], arr[0] + 0, *(arr + 0), *(arr + 0) + 0 모두가 같은 주소를 나타낸다.
이는 arr[0][0] (0열의 시작)의 주소와 같다는 것을 알 수 있다.
&arr[0][0] == arr[0] == arr[0] + 0 == *(arr + 0) == *(arr + 0) + 0
아래는 이해를 돕기 위한 그림이다.
모두 주소를 나타낸다.
값을 나타내는 것은 어떨까?
*&arr[0][1], 즉 arr[0][1] 이 값을 나타낸다는 것은 알고 있을 것이다.
*(*(arr + 0) + 1), *(arr[0] + 1)
이렇게 주소에 참조 연산자(*) 를 달아주면 값을 나타내는 것이다.
int arr[2][3] = {10, 20, 30, 40, 50, 60};
printf("%d %d %d", arr[0][2], *(arr[0] + 2), *(*(arr + 0) + 2));
// 30 30 30
이해를 돕기 위한 그림이다.
포인터 변수를 이용한 2차원 배열의 접근
위에서 본 것은 참조 연산자와 주소 연산자, 배열 이름으로 본 2차원 배열의 주소와 값 표기였다.
이제는 포인터 변수를 통해 2차원 배열에 접근하는 방식을 알아보려고 한다.
1차원 포인터 변수 p는 2차원 배열 arr[2][3]을 1차원으로만 접근할 수 있다.
2차원 배열이라고 하더라도, 1차원 포인터 변수는 이 배열을 1차원적으로 접근한다.
int arr[2][3] = {10, 20, 30, 40, 50, 60};
int *p = arr; // p = arr[0] -> 시작 주소 저장
printf("%x %x %X %X\n", &p[1], arr[0] + 1, &p[5], arr[1] + 2);
// 4bbffa04 4bbffa04 4BBFFA14 4BBFFA14
코드를 통해서도 알 수 있고, 아래 그림을 통해서도 알 수 있다.
1차원 포인터를 통한 주소의 표현은 다음과 같다.
1차원 포인터를 통한 값 표현은 다음과 같다.
이렇게 1차원 포인터를 통해서는 1차원적인 접근만 가능하고,
2차원 포인터 변수의 경우 아예 2차원 배열으로의 접근이 어렵다는 것을 알게 되었다.
(2차원 포인터 변수는 1차원 포인터 변수의 주소만 저장하기 때문이다)
2차원 배열을 2차원적으로 접근하기 위해서는 어떻게 해야 할까?
배열 포인터를 사용하면 된다. (배열 포인터에 관한 설명은 다음 포스팅 참고)
'C' 카테고리의 다른 글
[C] 포인터와 문자열 (0) | 2023.11.12 |
---|---|
[C] 포인터와 1차원 배열 (0) | 2023.10.26 |
[C] 배열 포인터, 포인터 배열 (0) | 2023.10.26 |
[C] 포인터와 함수 (0) | 2023.10.26 |
[C] 포인터와 다차원 포인터 (0) | 2023.10.24 |