alt

4-2일 포인터

Shared on April 19, 2026

포인터 개념과 활용 – C 프로그래밍 강의 요약

개요

이 강의에서는 C 언어에서 포인터의 정의, 사용법, 그리고 포인터를 활용한 메모리 접근과 배열과의 관계, 동적 메모리 할당에 대해 설명한다. 포인터를 이해하면 변수에 직접 접근하지 않고도 간접적인 메모리 조작이 가능해지며, 이는 함수 인자 전달, 배열 순회, 동적 데이터 구조 구현 등에서 필수적이다.

핵심 개념

개념설명
포인터메모리 주소를 저장하는 변수. int *iptr;처럼 *를 붙여 선언.
역참조 연산자(*)포인터가 가리키는 주소에 있는 실제 값을 읽거나 쓴다. *iptr = 10;
주소 연산자(&)변수의 메모리 주소를 가져온다. iptr = &i;
포인터 산술iptr + 1 은 포인터가 가리키는 다음 정수(4바이트) 위치로 이동한다. -도 마찬가지.
배열과 포인터배열 이름은 첫 번째 요소의 상수 포인터이다. 배열 접근은 arr[3]*(arr + 3)이 동등.
동적 메모리 할당malloc(size) 으로 운영체제로부터 메모리 요청, 반환 주소를 포인터에 저장. 사용 후 free(ptr) 로 반환.
스코핑 규칙과 포인터지역 변수는 함수 내부에서만 접근 가능. 하지만 &i 를 인자로 넘겨 포인터를 통해 외부에서 접근 가능.

상세 내용

1. 포인터 선언과 사용

  • int *iptr; → 포인터 변수 iptr 선언
  • iptr = &i;i의 주소를 iptr에 저장
  • *iptr = 20;iptr가 가리키는 주소에 20 저장 (i값이 20으로 변경)

2. 간접 접근의 장점

  • 함수 인자 전달: void swap(int *x, int *y) { int t = *x; *x = *y; *y = t; }
    swap(&i, &j); 로 호출하면 지역 변수 i, j를 직접 바꾸지 않고 포인터를 통해 값 교환.
  • 스코프 회피: 지역 변수를 포인터로 전달하면 함수 외부에서도 값을 조작 가능.

3. 포인터 산술

  • iptr + 1 → 다음 정수(4바이트) 주소.
  • iptr - 1 → 이전 정수 주소.
  • iptr++ / iptr-- 은 포인터 자체를 이동.

4. 배열과 포인터

  • 배열 선언: int arr[10];
  • arr&arr[0] 와 동일한 상수 포인터.
  • arr[3]*(arr + 3) 와 동일.
  • 포인터 변수를 배열처럼 사용해도, 배열 이름은 상수이므로 재할당 불가.

5. 동적 메모리 할당

int *ptr = (int *)malloc(10 * sizeof(int)); // 10개의 int 공간 확보 if (ptr == NULL) { /* 할당 실패 처리 */ } for (int i = 0; i < 10; i++) ptr[i] = i * 10; // 포인터로 배열 접근 free(ptr); // 사용 후 해제
  • malloc 은 바이트 단위로 요청하므로 sizeof 로 타입 크기 계산 필요.
  • free 를 호출하지 않으면 메모리 누수 발생.

6. 실전 활용 예시

  1. 배열 초기화
    포인터를 이용해 for (int i=0; i<10; i++) *(ptr+i) = i*10;
  2. 동적 2차원 배열
    int **matrix = malloc(rows * sizeof(int *));
    각 행을 malloc(cols * sizeof(int)) 로 할당 후 사용.
  3. 메모리 누수 방지
    프로그램 종료 전 free 호출, 혹은 calloc 으로 초기화.

7. 자주 발생하는 실수

  • 포인터 변수에 비정상적인 주소를 저장 → 프로그램 충돌
  • 배열 이름을 변수처럼 재할당 시도 → 컴파일 오류
  • mallocNULL 체크 미흡 → 지연 충돌
  • free 이전에 포인터를 다른 주소에 할당 → 메모리 누수

8. 학습 포인트

  • 포인터는 변수의 주소를 저장하는 변수이며, * (역참조)와 & (주소연산자)로 사용된다.
  • 포인터 산술은 메모리 주소 단위(타입 크기)로 계산된다.
  • 배열과 포인터는 문법적으로 비슷하지만, 배열 이름은 상수 포인터라 재할당 불가.
  • 동적 메모리 할당은 운영체제와의 상호작용이며, 반드시 free 로 해제해야 한다.

핵심: 포인터를 이해하면 함수 간 데이터 전달, 배열 순회 그리고 동적 데이터 구조를 효율적으로 구현할 수 있다. 직접 값을 쓰는 것보다 포인터를 통해 간접적으로 접근하면 스코프 제한을 넘어설 수 있다.