Skip to main content
double pointer

이중 포인터

이중 포인터 개념

포인터는 포인터 변수가 저장한 다른 변수의 주소를 사용하여 값에 접근하거나 변경할 수 있습니다. 하지만 만약 포인터 변수 자체의 주소를 저장하기 위해서는 어떻게 해야 할 까요? 바로 이중 포인터를 사용하여 포인터 변수의 주소를 저장합니다.

int **p1;

위와 같이 두 개의 **를 사용하여 포인터 변수 자체의 주소를 저장할 수 있는 이중 포인터를 선언할 수 있습니다. 여기서 다시 이중 포인터 변수 자체를 저장하려면 아래와 같이 선언하면 됩니다.

int ***p2

간단한 이중 포인터 예제

#include <stdio.h>

int main() {

    int  a = 10;
    int  *p1;  // 포인터 변수 선언
    int  **p2; // 이중 포인터 변수 선언
    
    p1 = &a;   // a의 주소를 저장
    p2 = &p1;  // 포인터 변수인 p1의 주소를 이중 포인터 p2에 저장

    // 변수 자체의 주소를 출력
    printf("Address of a = %u\n", &a);
    printf("Address of p1 = %u\n", &p1);
    printf("Address of p2 = %u\n\n", &p2);

    // 이중 포인터 p2가 가리키는 값 출력 
    printf("Value at the address stored by p2 = %u\n", *p2);
    
    // 포인터 p1이 가리키는 값 출력
    printf("Value at the address stored by p1 = %d\n\n", *p1);

    // 이중 포인터 p2가 가리키는 최종 값 출력
    printf("Value of **p2 = %d\n", **p2);

    return 0;
}

OUTPUT
Address of a = 255089676
Address of p1 = 255089680
Address of p2 = 255089688
Value at the address stored by p2 = 255089676
Value at the address stored by p1 = 10
Value of **p2 = 10
double pointer
  1. 위 그림과 같이 p1은 a변수의 주소를 저장하고 있고 p2는 p1의 주소를 저장하고 있습니다. p2는 이중 포인터므로 오직 포인터 변수 자체의 주소만을 저장할 수 있습니다.
  2. *p2는 p2가 가리키는 값에 접근하는 역참조 연산자를 사용했으므로 p1이 저장하고 있는 값 즉 a 변수의 주소값을 출력합니다.
  3. **p는 결국 *(*p2)입니다. 2번 항목의 *p2는 a 변수의 주소값이고 거기에 값에 접근하는 *(역참조 연산자)가 한번 더 사용됐으므로 결과적으로 a의 값이 출력됩니다.

선언 시의 *는 포인터 변수의 선언을 뜻하고 사용 시의 *는 역참조 연산자로 포인터 변수가 가리키는 값에 접근하는 역활을 합니다.

이중 포인터는 어디서 사용될까요?

다소 어려울 수 있으나 하나의 예로 함수가 포인터 변수의 주소를 인자로 받아 동적으로 메모리 할당을 할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

void allocate(int** p)
{
  // 포인터 변수가 가리키는 곳에 동적으로 메모리 공간 할당
  *p = (int*)malloc(sizeof(int)); 
}

int main()
{
  // 초기에 널 포인터 선언  
  int* p = NULL;
  
  // 함수에 포인터 변수 자체의 주소를 인수로 전달
  allocate(&p);
  
  // 할당된 메모리 공간에 값 입력
  *p = 10;

  // 출력
  printf("%d", *p);

  // 동적으로 생성된 메모리 공간 제거
  free(p);
}

그 외에 문자열은 이중 포인터를 사용하는 좋은 예입니다. 문자열 자체는 포인터이므로 문자열을 가리킬 필요가 있을 때 이중 포인터를 사용합니다.

<< 다음 혼자 공부하는 C언어 이전 >>

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다