티스토리 뷰
반응형
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 는 포인터의 주소
연습 문제 ✍️
- 변수 a=100 을 이중 포인터를 이용해 출력해보세요.
- 포인터 p 가 가리키는 변수를 함수에서 바꿀 수 있도록 이중 포인터를 이용해 구현하세요.
- 동적 메모리를 이중 포인터로 할당하고, 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 (이중 포인터)는 “포인터의 주소”를 담는다.
- 포인터 자체를 함수에서 바꾸고 싶을 때 이중 포인터 사용.
- 동적 메모리 주소를 함수에서 되돌려줄 때도 이중 포인터가 깔끔하다.
반응형
'[문법] C언어' 카테고리의 다른 글
12) C언어 함수 포인터와 void 포인터 완전정리 (2) | 2025.09.02 |
---|---|
11) C언어 다차원 배열과 포인터 완전정리: 2차원 배열부터 포인터까지 (2) | 2025.09.02 |
9) C언어 포인터와 함수: 배열 전달, Call by Value vs Reference, const 정리 (2) | 2025.09.01 |
8) C언어 포인터와 배열 완전정리: 관계, 연산, 문자열, 포인터 배열 (2) | 2025.09.01 |
7) C언어의 1차원 배열과 포인터에 대해 알아보자 (2) | 2025.09.01 |