- 더블 포인터
1. 더블 포인터
포인터 변수는 메모리 주소값을 저장한다. 포인터 변수를 선언하게 되면 주소값을 저장하기 위해 공간을 새로 할당한다. 당연히 그 공간에 대한 주소값도 존재하게 된다. 이 포인터 변수의 주소값을 저장하는 포인터 변수를 선언하면 그게 바로 더블 포인터가 된다. 눈치 챘겠지만 3차, 4차 이상의 다중 포인터를 선언하는 것도 가능하다.
함수에서 매개변수로 배열이 존재한다면,
void function1(int arr[]) {
...
}
위와 같은 형태로 존재할 것이다. 그러나 매개변수를 이렇게 선언하는 것은 프로그래머가 읽을 때 배열이라는 형태라고 생각하도록 유도하기 위함이지 실제로는 포인터로 받게 된다. 즉, 위 코드는 다음 코드로 변환된다.
void function1(int * arr) {
...
}
마찬가지로 2차원 배열도 인수를 더블 포인터 형태로 받게 된다. (2차원 배열을 매개변수로 받는 함수를 구현하는 것은 사실 조금 까다롭다.)
다음 예제 코드로 선언하는 방법을 살펴보자.
int num = 5;
int * ptr = #
int ** dptr = &ptr;
// num == *ptr == **dptr
// &num == ptr, &ptr == dptr
더블 포인터는 **을 사용하여, 3중 포인터는 ***을 사용하여 선언한다. 이제 주석처리한 부분을 보라! 포인터 연산에서 *연산은 값이 나올 때까지 가능하다. 하지만 &&num 가 dptr와 같을 거라 생각한다면 그건 틀린 생각이다. dptr이 존재하려면 포인터 변수인 ptr가 먼저 생성되어야 한다. 어떤 변수의 주소값의 주소값, 논리적으로도 이상하지 않은가?
앞서 배열은 포인터라고 한 적이 있다. 더블 포인터를 이해하기 위해 2차원 배열을 이용하려고 한다. 포인터 연산에서 다음 연산이 어떤 결과를 갖게될까?
int arr[5][3] = {0, };
arr+1; // 연산 1
arr[0]+1; // 연산 2
printf("%p %p %p", arr, arr+1, arr[0]+1);
arr이 1000번지라면 arr+1과 arr[0]+1 모두 1004번지를 가리키게 될까? 결과는 arr+1은 1012번지를, arr[0]+1은 1004번지를 가리킨다. arr은 더블 포인터, arr[0]은 포인터이다. 둘 모두 주소값은 같지만 arr의 다음 값은 arr[1]인 반면, arr[0]의 다음 값은 &(arr[0][1])이다. 즉, arr+1연산에서, 포인터는 int 자료형의 주소값이 아닌 int [3] 자료형의 주소값으로 인식한다.(C에서 실제로 이런 자료형은 없다. 하지만 어떤 의미로 사용했는지 이해하리라 생각한다.)
'C언어' 카테고리의 다른 글
C언어 전역변수 초기화 (0) | 2021.03.30 |
---|---|
C언어 기초 part 2-7. 함수 포인터 (0) | 2020.06.10 |
C언어 연재, 앞으로의 계획 (0) | 2020.03.24 |
C언어 기초 part 2-4. 문자열 (2) | 2020.03.20 |
C언어 기초 part 2-3. 포인터 (20.03.27. 내용 추가) (0) | 2020.03.03 |