산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 포인터 마스터: 기초부터 포인터 연산, 배열/함수 포인터, 동적 할당까지

포인터는 C의 핵심이자 가장 강력한 도구입니다. 메모리 주소를 직접 다루며 동적 할당, 배열 조작, 함수 콜백, 자료구조 구현의 기반이 됩니다. 기초부터 실전 패턴까지 체계적으로 정리합니다.

포인터 기초

메모리 주소와 포인터

int var = 42;
int *ptr = &var;  // ptr은 var의 주소 저장

printf("var 값: %d\n", var);        // 42
printf("var 주소: %p\n", (void*)&var); // 0x7ffc...
printf("ptr 값(주소): %p\n", (void*)ptr); // 0x7ffc... (같음)
printf("ptr이 가리키는 값: %d\n", *ptr);  // 42 (역참조)

포인터 선언 문법

int *p1, *p2;    // 둘 다 int* (각 변수마다 * 붙이기 권장)
int *p3, p4;     // p3만 포인터, p4는 int - 혼동 주의!

// 읽는 법: 오른쪽에서 왼쪽으로
int *p;          // p는 int를 가리키는 포인터
int **pp;        // pp는 int*를 가리키는 포인터 (이중 포인터)
int *arr[10];    // int* 배열 (포인터 배열)
int (*parr)[10]; // int[10] 배열 포인터 (배열 포인터)
int *func();     // int* 반환 함수
int (*fp)(int);  // int(int) 함수 포인터

포인터 연산 (Pointer Arithmetic)

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;

printf("%d\n", *p);       // 10
printf("%d\n", *(p+2));   // 30
p++;                      // 다음 요소로
printf("%d\n", *p);       // 20
p += 2;
printf("%d\n", *p);       // 40

ptrdiff_t diff = &arr[4] - &arr[1];  // 3 (요소 3개 차이)

NULL 포인터와 검사

동적 메모리 할당 (<stdlib.h>)

안전한 할당 패턴

int *arr = malloc(100 * sizeof(int));
if (!arr) {
    fprintf(stderr, "메모리 할당 실패\n");
    exit(EXIT_FAILURE);
}
// 사용...
free(arr);
arr = NULL;  // 댕글링 포인터 방지

흔한 버그

배열과 포인터 심화

포인터 배열 (Pointer Array)

char *names[] = {"Alice", "Bob", "Charlie"};  // 문자열 리터럴 배열
// names[i]는 char* (각 문자열 주소)

int *ptrs[10];  // int 포인터 10개 배열

배열 포인터 (Array Pointer)

int matrix[3][4];
int (*row)[4] = matrix;  // int[4] 타입 포인터

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 4; j++) {
        printf("%d ", row[i][j]);  // row[i] ≡ *(row+i) ≡ matrix[i]
    }
}

함수 포인터

// 선언
int (*compare)(const void*, const void*);

// 대입
compare = &strcmp;  // & 생략 가능
compare = strcmp;

// 호출
int result = compare("a", "b");  // 또는 (*compare)("a", "b")

// typedef로 간소화
typedef int (*CmpFunc)(const void*, const void*);
CmpFunc cmp = strcmp;

실전: qsort 콜백

int cmp_int(const void *a, const void *b) {
    int ia = *(const int*)a;
    int ib = *(const int*)b;
    return (ia > ib) - (ia < ib);  // 오버플로 안전 비교
}

int arr[] = {5, 2, 8, 1, 9};
qsort(arr, 5, sizeof(int), cmp_int);  // 정렬됨

포인터와 const

함수용도반환해제
malloc(size)미초기화 메모리 할당void* (성공) / NULL (실패)free()
calloc(n, size)0 초기화된 배열 할당void* / NULLfree()
realloc(ptr, size)크기 조정 (확장/축소)새 주소 / NULL (실패 시 원본 유지)free()
free(ptr)메모리 해제void-
aligned_alloc(align, size) (C17)정렬된 메모리 할당void* / NULLfree()

void 포인터 (Generic Pointer)

void *raw = malloc(100);
int *arr = raw;  // 암시적 변환 OK (C에서만, C++은 캐스팅 필요)
free(raw);

제약/제한 포인터 (C99 restrict)

void copy(int *restrict dst, const int *restrict src, size_t n) {
    for (size_t i = 0; i < n; i++) dst[i] = src[i];
    // dst와 src 영역 겹치지 않음 보장 → 적극적 최적화 가능
}

모범 사례

C 언어

  1. C 변수, 상수, 리터럴: 완전 가이드
  2. C 저장 클래스 이해: 범위, 생명주기, 성능
  3. C 포인터 마스터하기: 실전 중심 전문가 가이드
  4. C 언어에서 배열과 포인터의 관계 이해하기
  5. C 프로그래밍: 주소와 포인터를 함수에 전달하기 – 실전 가이드
  6. C 구조체와 포인터 마스터하기: 실전 가이드
  7. 파이썬 global 키워드 마스터하기: 사용법과 타이밍
  8. C++ 포인터 완전 정복: 개념, 예제, 실전 활용
  9. C 변수, 데이터 타입, 상수 – 실전 가이드
  10. C 포인터 완벽 가이드: 타입, 사용법, 모범 사례
선언읽기쓰기포인터 변경이름
int *p가능가능가능-
const int *p / int const *p가능불가가능상수 포인터 (Pointer to const)
int *const p가능가능불가포인터 상수 (Const pointer)
const int *const p가능불가불가상수 포인터 상수