본문으로 이동
메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

C 언어 포인터(Pointer in C, 포인터)는 메모리의 주소를 저장하는 변수로, 변수나 함수, 배열 등의 위치를 가리킬 수 있는 기능을 제공한다.

포인터는 C 언어의 핵심 개념 중 하나로, 메모리 관리, 동적 할당, 배열 및 함수 간 데이터 전달 등에 필수적으로 사용된다. 일반 변수는 값을 저장하지만, 포인터는 해당 값이 저장된 메모리의 주소를 저장한다.

선언과 초기화

편집 원본 편집

포인터는 자료형 뒤에 `*`를 붙여 선언하며, `&` 연산자를 사용해 주소값을 대입한다.

  • 선언 형식: `자료형 *포인터이름;`
  • 예:
    • `int *p;` → 정수형을 가리키는 포인터 선언
    • `int a = 10;`
    • `p = &a;` → 변수 a의 주소를 포인터 p에 저장

포인터가 가리키는 주소에 접근하려면 `*` 연산자를 사용한다. 이를 간접 참조(dereferencing)라고 한다.

  • 예:
    • `*p = 20;` → p가 가리키는 변수의 값을 20으로 변경

포인터는 정수값을 더하거나 뺄 수 있으며, 이는 해당 자료형의 크기 단위로 이동한다.

  • 예:
    • `p + 1` → 다음 요소(예: int형이면 +4바이트)를 가리킴

같은 배열 안을 가리키는 두 포인터는 <, >, == 로 비교할 수 있다. 비교 결과는 가리키는 원소의 위치(첨자) 순서와 같다. 두 포인터의 차(q - p)는 그 사이 원소 개수다.

배열의 양 끝에서 안쪽으로 좁혀 오며 짝을 처리하는 재귀 함수가 대표적인 예다.

void func(int *p, int *q) {
    if (p > q) return;            /* 두 포인터가 엇갈리면 끝 */
    printf("%d ", *p + *q);
    func(p + 1, q - 1);           /* 앞은 한 칸 뒤로, 뒤는 한 칸 앞으로 */
}
int a[] = {3, 1, 4, 1, 5};
func(a, a + 4);                   /* 출력: 8 2 8 */
  • 1회 : p 는 a[0](3), q 는 a[4](5) → 8
  • 2회 : a[1](1) + a[3](1) → 2
  • 3회 : p 와 q 가 모두 a[2](4) 를 가리킨다. p > q 가 아니므로 4 + 4 → 8
  • 4회 : p 는 a[3], q 는 a[1] 이라 p > q 가 되어 끝난다
  • 재귀의 흐름은 재귀 함수 참조

배열과 포인터

편집 원본 편집

배열 이름은 해당 배열의 첫 번째 요소를 가리키는 포인터처럼 동작한다.

  • 예:
    • `int arr[3] = {1, 2, 3};`
    • `int *p = arr;`
    • `p[1]` 또는 `*(p + 1)` → 2

배열 포인터와 2차원 배열

편집 원본 편집

배열 포인터는 배열 하나 전체를 가리키는 포인터다. int (*p)[3]; 은 "int 3개짜리 배열을 가리키는 포인터" 이고, 괄호를 빼면 int *p[3];(포인터 3개짜리 배열, 포인터 배열)이 되어 뜻이 달라진다.

int arr[2][3] = {1, 2, 3, 4, 5, 6};   /* arr[0] = {1,2,3}, arr[1] = {4,5,6} */
int (*p)[3] = arr;                     /* p 는 arr[0] 행을 가리킨다 */
  • p[i] 는 i 번째 행(*(p + i)), p[i] + j 는 그 행의 j 번째 원소 주소, *(p[i] + j) 는 그 값이다
  • p + 1 은 원소 하나가 아니라 행 하나(int 3개, 12바이트)만큼 이동한다
  • 위 예에서 *(p[0] + 1) = 2, *(p[1] + 2) = 6, *(*(p + 1) + 0) = 4, *(*(p + 1) + 1) = 5 이다

함수와 포인터

편집 원본 편집

포인터는 함수 인자로 전달되어 원본 데이터를 변경할 수 있게 한다(주소 전달 방식).

  • 예:
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

동적 메모리 할당

편집 원본 편집

포인터는 malloc, calloc, realloc 등을 사용하여 런타임 중에 메모리를 할당받는 데 사용된다.

  • 예:
int *p = (int *)malloc(sizeof(int) * 5);

다음은 기본적인 포인터 사용 예제이다:

#include <stdio.h>

int main() {
    int a = 100;
    int *p = &a;

    printf("변수 a의 값: %d\n", a);
    printf("포인터 p가 가리키는 값: %d\n", *p);
    printf("변수 a의 주소: %p\n", &a);
    printf("포인터 p의 값: %p\n", p);

    return 0;
}
  • Kernighan, Brian W., and Ritchie, Dennis M. *The C Programming Language*. Prentice Hall, 1988.
  • King, K. N. *C Programming: A Modern Approach*. W. W. Norton & Company, 2008.