본문 바로가기
카테고리 없음

C 포인터의 기초 배우기 (변수, 메모리, 참조)

by info95686 2025. 10. 2.

C 포인터의 기초 배우기
C 포인터의 기초 배우기

C언어에서 포인터(pointer)는 초보자들이 가장 어려워하는 개념 중 하나입니다. 포인터는 단순히 “값을 저장하는 변수”가 아니라, 변수의 메모리 주소를 저장하는 특별한 변수입니다. 이 개념은 추상적이고 낯설지만, 이해하게 되면 C언어의 강력한 특징들을 활용할 수 있습니다. 배열, 문자열, 동적 메모리 할당, 함수 호출에서 포인터는 핵심적인 역할을 합니다. 포인터를 모르면 C언어는 반쪽짜리로만 활용되지만, 포인터를 알면 시스템 프로그래밍, 임베디드, 네트워크, 운영체제 개발까지 문이 열립니다. 이번 글에서는 변수, 메모리, 참조라는 세 가지 키워드를 중심으로 포인터의 기초 개념을 풀어내고, 간단한 예제를 통해 직관적으로 설명해 보겠습니다.

변수와 포인터의 관계

int num = 10;

int *p;
p = #

printf("%d\n", *p); // 10 출력

이처럼 포인터는 변수 이름과 값 사이에서 주소라는 매개체를 다룹니다. 변수를 직접 다루는 대신, “변수가 저장된 위치”를 조작하는 셈이죠. 결국 포인터는 메모리 상의 위치를 가리키는 화살표와 같다고 생각하면 이해하기 쉽습니다.

메모리 주소와 포인터의 역할

int num = 42;
int *ptr = #

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

포인터를 통해 값이 저장된 위치를 직접 읽고 쓸 수 있습니다. 포인터를 잘 다루면 메모리를 절약할 수 있고, 복잡한 데이터 구조를 효율적으로 구현할 수 있습니다. 하지만 잘못 쓰면 프로그램이 깨지거나 보안 취약점으로 이어질 수 있으므로 주의가 필요합니다.

참조와 함수 인자 전달

void changeValue(int *x) {
    *x = 100;
}

int main() {
    int num = 10;
    changeValue(&num);
    printf("%d\n", num); // 100 출력
    return 0;
}

포인터를 사용하면 함수가 원본 데이터를 직접 수정할 수 있습니다. 이는 C언어에서 배열이나 구조체를 함수에 넘길 때 특히 중요합니다. 데이터가 클수록 복사 비용이 커지는데, 포인터를 쓰면 복사하지 않고 바로 참조할 수 있어 효율적입니다.

배열과 포인터의 관계

int arr[3] = {10, 20, 30};
printf("%p\n", arr);     // 배열의 시작 주소
printf("%p\n", &arr[0]); // 첫 번째 원소 주소

printf("%d\n", *(arr + 1)); // 20 출력

배열 이름은 곧 배열 첫 번째 원소의 주소를 의미합니다. 따라서 포인터 연산을 통해 배열 원소에 접근할 수 있고, 문자열 처리도 같은 원리로 동작합니다.

동적 메모리와 포인터

int *arr = (int *)malloc(5 * sizeof(int));
if (arr == NULL) {
    printf("메모리 할당 실패\n");
    return 1;
}

for (int i = 0; i < 5; i++) {
    arr[i] = i * 10;
}

for (int i = 0; i < 5; i++) {
    printf("%d ", arr[i]);
}

free(arr);

동적 메모리를 할당하면 실행 중에 원하는 크기만큼 메모리를 확보하고 자유롭게 사용할 수 있습니다. 포인터는 이 메모리의 시작 주소를 가리키며, 반드시 free로 해제해야 메모리 누수를 방지할 수 있습니다.

결론: 포인터는 C언어의 본질

포인터는 변수를 가리키는 주소를 저장하는 특별한 변수입니다. * 연산자를 통해 포인터가 가리키는 값에 접근할 수 있고, & 연산자를 통해 주소를 얻을 수 있습니다. 이 원리를 이해하면 참조, 배열, 문자열, 동적 메모리 관리 등 다양한 기능을 활용할 수 있습니다. 포인터를 잘 이해하면 효율적인 메모리 활용과 빠른 성능을 얻을 수 있으며, C언어가 시스템 프로그래밍에 강력한 이유를 실감할 수 있습니다.