반응형
Advanced Uses of Pointers / 포인터의 고급 활용
1. Dynamic Memory Allocation / 동적 메모리 할당
- 개념: 프로그램 실행 중 메모리를 동적으로 할당하고 해제.
- 주요 함수:
- malloc: 메모리를 할당.
- calloc: 초기화된 메모리를 할당.
- realloc: 기존 메모리 크기를 조정.
- free: 할당된 메모리를 해제.
(1) malloc
- 설명: 지정한 크기의 메모리를 할당하며, 초기화되지 않은 상태로 반환.
- 형식: void *malloc(size_t size);
예제:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(5 * sizeof(int)); // 정수 5개 크기의 메모리 할당
if (arr == NULL) {
perror("malloc 실패");
return 1;
}
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
printf("malloc으로 할당된 메모리 값: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr); // 메모리 해제
return 0;
}
(2) calloc
- 설명: 지정한 크기의 메모리를 할당하고, 0으로 초기화.
- 형식: void *calloc(size_t nmemb, size_t size);
예제:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = calloc(5, sizeof(int)); // 정수 5개 크기의 메모리 할당 및 초기화
if (arr == NULL) {
perror("calloc 실패");
return 1;
}
printf("calloc으로 초기화된 메모리 값: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]); // 모든 값이 0으로 초기화됨
}
printf("\n");
free(arr); // 메모리 해제
return 0;
}
(3) realloc
- 설명: 기존 메모리 크기를 조정하거나 확장.
- 형식: void *realloc(void *ptr, size_t size);
예제:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(3 * sizeof(int)); // 정수 3개 크기의 메모리 할당
if (arr == NULL) {
perror("malloc 실패");
return 1;
}
for (int i = 0; i < 3; i++) {
arr[i] = i + 1;
}
printf("realloc 이전 값: ");
for (int i = 0; i < 3; i++) {
printf("%d ", arr[i]);
}
printf("\n");
arr = realloc(arr, 5 * sizeof(int)); // 메모리 크기를 5개로 확장
if (arr == NULL) {
perror("realloc 실패");
return 1;
}
for (int i = 3; i < 5; i++) {
arr[i] = i + 1; // 추가된 공간 초기화
}
printf("realloc 이후 값: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr); // 메모리 해제
return 0;
}
(4) free
- 설명: 동적으로 할당된 메모리를 해제.
- 형식: void free(void *ptr);
예제:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(5 * sizeof(int)); // 동적 메모리 할당
if (arr == NULL) {
perror("malloc 실패");
return 1;
}
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
printf("메모리 값: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr); // 메모리 해제
printf("메모리 해제 완료\n");
return 0;
}
2. Function Pointers / 함수 포인터
- 개념: 함수를 가리키는 포인터를 사용하여 동적으로 함수를 호출.
- 주요 활용:
- 콜백 함수 구현.
- 동적 함수 호출.
예제: 함수 포인터 사용
#include <stdio.h>
void say_hello() {
printf("Hello, World!\n");
}
void say_goodbye() {
printf("Goodbye, World!\n");
}
int main() {
void (*func_ptr)(); // 함수 포인터 선언
func_ptr = say_hello;
func_ptr(); // Hello, World!
func_ptr = say_goodbye;
func_ptr(); // Goodbye, World!
return 0;
}
3. Array of Pointers / 포인터 배열
- 개념: 포인터 배열을 사용하여 여러 문자열이나 다차원 데이터를 저장.
예제: 문자열 배열 관리
#include <stdio.h>
int main() {
const char *messages[] = {"Hello", "World", "C Programming"};
for (int i = 0; i < 3; i++) {
printf("%s\n", messages[i]);
}
return 0;
}
4. Pointer to Pointer / 이중 포인터
- 개념: 포인터를 가리키는 포인터를 사용하여 동적 메모리를 관리하거나 복잡한 데이터 구조를 처리.
예제: 이중 포인터를 이용한 2D 배열 동적 할당
#include <stdio.h>
#include <stdlib.h>
int main() {
int rows = 3, cols = 4;
int **matrix = malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
matrix[i] = malloc(cols * sizeof(int));
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
free(matrix[i]);
}
free(matrix);
return 0;
}
5. Void Pointers / void 포인터
- 개념: 특정 데이터 타입에 구애받지 않는 포인터. 타입 캐스팅이 필요.
예제: void 포인터 사용
#include <stdio.h>
void print_value(void *ptr, char type) {
switch (type) {
case 'i':
printf("정수: %d\n", *(int *)ptr);
break;
case 'f':
printf("실수: %f\n", *(float *)ptr);
break;
case 'c':
printf("문자: %c\n", *(char *)ptr);
break;
}
}
int main() {
int num = 42;
float pi = 3.14f;
char letter = 'A';
print_value(&num, 'i');
print_value(&pi, 'f');
print_value(&letter, 'c');
return 0;
}
6. Linked Lists / 연결 리스트
- 개념: 포인터를 사용하여 노드를 동적으로 연결.
- 활용:
- 데이터 삽입 및 삭제가 빈번한 상황에서 효율적.
예제: 연결 리스트 구현
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
void print_list(Node *head) {
while (head != NULL) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
Node *head = malloc(sizeof(Node));
Node *second = malloc(sizeof(Node));
Node *third = malloc(sizeof(Node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
print_list(head);
free(third);
free(second);
free(head);
return 0;
}
포인터 사용에 대해 연습하는 좋은 방법은 알고리즘 문제를 직접 풀어보는 것이라고 생각합니다.
알고리즘 & 자료구조 카테고리를 참조해주세요!
💡 도움이 되셨다면 댓글과 공감 부탁드립니다! 😊
📌 더 많은 알고리즘 풀이와 프로그래밍 자료는 블로그에서 확인하세요!
✉️ 문의나 피드백은 댓글이나 이메일로 남겨주세요.
반응형
'Computer Science > C 언어' 카테고리의 다른 글
[C언어 21] C언어로 객체지향 프로그래밍 흉내내기 (0) | 2024.12.29 |
---|---|
[C언어 20] Declarations 선언문 (0) | 2024.12.28 |
[C언어 18] File Input/Output (파일 입출력) (0) | 2024.12.25 |
[C 17]Understanding Generic Programming / 제네릭 프로그래밍 이해 (0) | 2024.12.15 |
[C #17] 구조체(Structs), 공용체(Unions), 열거형(Enums) (0) | 2024.12.14 |