티스토리 뷰

반응형

 

C언어 기초 Chapter 16: 포인터의 포인터 (이중 포인터 이해와 활용)


16-1. 포인터의 포인터에 대한 이해

기본 개념

  • 포인터도 변수이므로, 그 포인터의 주소를 저장하는 또 다른 포인터를 만들 수 있음
  • 이를 이중 포인터(double pointer) 라고 함
  • 선언 방식:
int **pp;

예제

#include <stdio.h>
int main(void) {
    int a = 10;
    int *p = &a;     // int형 변수 a를 가리킴
    int **pp = &p;   // 포인터 p의 주소를 가리킴

    printf("a = %d\n", a);
    printf("*p = %d\n", *p);
    printf("**pp = %d\n", **pp);

    return 0;
}

👉 출력:

a = 10
*p = 10
**pp = 10

즉, **pp 는 결국 a 와 동일한 값을 참조함


16-2. 이중 포인터 변수와 포인터의 필요성

1) 포인터를 인자로 전달할 때 값 변경

  • 함수에서 포인터가 가리키는 대상을 바꾸고 싶을 때 이중 포인터가 필요함

예제: 포인터를 함수 안에서 수정하기

#include <stdio.h>

void changePointer(int **pp, int *newAddr) {
    *pp = newAddr;   // 포인터가 새로운 주소를 가리키도록 변경
}

int main(void) {
    int a = 10, b = 20;
    int *p = &a;

    printf("변경 전: *p = %d\n", *p);

    changePointer(&p, &b);   // p가 b를 가리키도록 변경

    printf("변경 후: *p = %d\n", *p);
    return 0;
}

👉 출력:

변경 전: *p = 10
변경 후: *p = 20

2) 동적 메모리 할당에서 활용

  • malloc 같은 함수를 사용하여 메모리를 동적으로 할당할 때,
  • 함수에서 새로운 메모리 주소를 반환해야 하는 경우 이중 포인터가 필요
#include <stdio.h>
#include <stdlib.h>

void allocArray(int **pp, int size) {
    *pp = (int *)malloc(size * sizeof(int));
}

int main(void) {
    int *arr = NULL;
    allocArray(&arr, 5);

    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
        printf("%d ", arr[i]);
    }
    free(arr);
    return 0;
}

👉 출력: 1 2 3 4 5


핵심 정리 ✅

  • 포인터의 포인터(**pp)는 결국 변수의 주소의 주소를 담음
  • 이중 포인터를 쓰는 경우:
    • 포인터 자체를 함수에서 수정해야 할 때
    • 동적 메모리 할당에서 함수로 주소를 반환할 때
  • **pp 는 실제 데이터, *pp 는 1차 포인터, pp 는 포인터의 주소

연습 문제 ✍️

  1. 변수 a=100 을 이중 포인터를 이용해 출력해보세요.
  2. 포인터 p 가 가리키는 변수를 함수에서 바꿀 수 있도록 이중 포인터를 이용해 구현하세요.
  3. 동적 메모리를 이중 포인터로 할당하고, 10칸짜리 배열에 1~10까지 저장 후 출력하세요.

 

 

👉 연습문제 정답은? ▼

 

Chapter 16 연습문제 풀이

1) 변수 a=100 을 이중 포인터로 출력

#include <stdio.h>

int main(void) {
    int a = 100;
    int *p = &a;     // a의 주소
    int **pp = &p;   // p의 주소(= a의 주소의 주소)

    printf("a = %d\n", a);
    printf("*p = %d\n", *p);
    printf("**pp = %d\n", **pp);  // 이중 포인터로 접근
    return 0;
}

출력 예시

a = 100
*p = 100
**pp = 100

2) 함수에서 포인터가 가리키는 대상 바꾸기(이중 포인터)

#include <stdio.h>

void redirect(int **pp, int *new_target) {
    *pp = new_target;   // pp가 가리키는 '포인터 변수'의 값(주소)을 변경
}

int main(void) {
    int x = 10, y = 20;
    int *p = &x;

    printf("변경 전: *p = %d\n", *p); // 10
    redirect(&p, &y);                 // p가 y를 가리키도록
    printf("변경 후: *p = %d\n", *p); // 20
    return 0;
}

출력 예시

변경 전: *p = 10
변경 후: *p = 20

3) 이중 포인터로 동적 메모리 할당(10칸) 후 1~10 저장·출력

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

int alloc_int_array(int **pp, size_t n) {
    *pp = (int *)malloc(n * sizeof(int));
    return (*pp != NULL);  // 성공 시 1, 실패 시 0
}

int main(void) {
    int *arr = NULL;

    if (!alloc_int_array(&arr, 10)) {
        fprintf(stderr, "메모리 할당 실패\n");
        return 1;
    }

    for (int i = 0; i < 10; i++) {
        arr[i] = i + 1;
    }

    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);
    return 0;
}

출력 예시

1 2 3 4 5 6 7 8 9 10

핵심 포인트 요약

  • pp (이중 포인터)는 “포인터의 주소”를 담는다.
  • 포인터 자체를 함수에서 바꾸고 싶을 때 이중 포인터 사용.
  • 동적 메모리 주소를 함수에서 되돌려줄 때도 이중 포인터가 깔끔하다.

 

반응형