Programming/C

C언어 - 포인터의 포인터(다중 포인터)

JunsuKim 2021. 10. 2.
728x90

배열도 다차원 배열이 있듯이 포인터에도 이중 포인터(더블 포인터), 다중 포인터가 존재한다.

포인터 변수를 가리키는 이중 포인터 변수

이중 포인터는 *연산자를 두 개 이어서 선언한다.

int **p;

포인터 변수도 메모리 공간에 할당이 되는 변수이다. 이를 대상으로 &연산이 가능하고, 이때 반환되는 주소 값은 "더블 포인터 변수"에 저장이 가능하다.

#include<stdio.h>

int main() {
    double num = 3.14;
    double *ptr = &num;
    double **dptr = &ptr;
    double *ptr2;
    
    printf("%9p %9p\n", ptr, *dptr);
    printf("%9g %9g\n", num, **dptr);
    ptr2 = *dptr;
    *ptr2 = 10.99;
    printf("%9g %9g\n", num, **dptr);
    return 0;
}

  • *dptr은 ptr을 의미
  • **dptr은 num을 의미
  • *dptr은 ptr을 의미하므로 ptr2도 num을 가리킴

포인터 변수 대상의 Call-by-reference

#include<stdio.h>

void Swap(int *p1, int *p2) {
    int *temp = p1;
    p1 = p2;
    p2 = temp;
}

int main() {
    int num1 = 10;
    int num2 = 20;
    int *ptr1, *ptr2;
    
    ptr1 = &num1;
    ptr2 = &num2;
    
    printf("*ptr1, *ptr2: %d %d\n", *ptr1, *ptr2);
    Swap(ptr1, ptr2);
    printf("*ptr1, *ptr2: %d %d\n", *ptr1, *ptr2);
    return 0;
}

/*
*ptr1, *ptr2: 10 20
*ptr1, *ptr2: 10 20
*/

이 코드는 잘못된 출력결과를 보인다. Swap함수를 통해 변경되어야 했을 값이 제대로 변환되지 않은 것이다.

이유가 무엇일까? p1은 ptr1과 별개고 p2는 ptr2와 별개이기 때문이다. 이 함수를 제대로 선언하기 위해서는 다음과 같은 방법이 필요하다.

#include<stdio.h>

void Swap(int **p1, int **p2) {
    int *temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}

int main() {
    int num1 = 10;
    int num2 = 20;
    int *ptr1, *ptr2;
    
    ptr1 = &num1;
    ptr2 = &num2;
    
    printf("*ptr1, *ptr2: %d %d\n", *ptr1, *ptr2);
    Swap(&ptr1, &ptr2);
    printf("*ptr1, *ptr2: %d %d\n", *ptr1, *ptr2);
    return 0;
}

/*
*ptr1, *ptr2: 10 20
*ptr1, *ptr2: 20 10
*/

Swap(&ptr1, &ptr2)를 보면 함수에 매개변수로 각각의 주소 값이 전달된다. 이는 다음의 형태와 같다.

따라서

int *temp = *p1;
*p1 = *p2;
*p2 = temp;

이 과정을 통해 값이 바뀌게 된다. 이게 잘 이해가 되지 않는다면 아래의 코드를 보자.

int *temp = ptr1;
ptr1 = ptr2;
ptr2 = temp;

*p1은 ptr1을 의미하고, *p2는 ptr2를 의미한다고 생각하면 된다.

결론적으로 ptr1에 저장된 값과 ptr2에 저장된 값이 바뀌게 되는 것이다.

다중 포인터 변수

*연산자가 둘 이상 사용되어 선언되는 포인터 변수를 다중 포인터 변수라 한다.

삼중 포인터를 보며 설명하겠다.

삼중 포인터는 이중 포인터를 가리키며 선언은 다음과 같다.

int ***tptr;

삼중 포인터 변수에 저장할 수 있는 값은 무엇일까?

이중 포인터 변수에는 포인터 변수의 주소를 저장했었다.

이와 같이 삼중 포인터 변수에는 이중 포인터 변수의 주소가 저장이 된다.

#include<stdio.h>

int main() {
    int num = 10;
    int *ptr = &num;
    int **dptr = &ptr;
    int ***tptr = &dptr;
    
    printf("%d %d %d %d\n", num, *ptr, **dptr, ***tptr);
    return 0;
}

// 10 10 10 10

 

728x90

댓글