포인터(pointer)란 다른 변수의 메모리 주소를 저장하는 변수를 말합니다. C 언어에서 포인터는 메모리에 직접 접근하고 제어할 수 있게 해주는 핵심 기능으로, 효율적인 프로그램 작성에 반드시 알아야 할 개념입니다.
포인터의 특징
불필요한 메모리 낭비를 줄여 메모리 공간을 절약할 수 있습니다.
메모리 위치에 직접 접근하기 때문에 실행 속도가 빠릅니다.
malloc(), free() 등과 함께 사용하면 메모리를 동적으로 할당하고 해제할 수 있어 메모리를 효율적으로 관리할 수 있습니다.
연결 리스트(linked list), 트리(tree) 등 다양한 자료구조 구현에 폭넓게 활용됩니다.
포인터 선언 방법
int *p;
위 선언문에서 'p'는 정수형(int) 변수의 주소를 저장하는 포인터 변수를 의미합니다. 자료형 뒤에 별표(*)를 붙이면 해당 자료형을 가리키는 포인터가 됩니다.
포인터 초기화
포인터 변수를 초기화할 때는 주소 연산자(&)를 사용합니다. 주소 연산자를 변수 앞에 붙이면 해당 변수의 메모리 주소를 얻을 수 있습니다.
int qty = 175; int *p; p = &qty;
이제 p에는 qty 변수의 메모리 주소가 저장되며, 이후 p를 통해 qty의 값을 읽거나 수정할 수 있습니다.
포인터를 통해 변수 값 접근하기
포인터가 가리키는 변수의 실제 값에 접근하려면 간접 참조 연산자(역참조 연산자, *)를 사용합니다.
예제 프로그램
#include<stdio.h>
void main(){
//변수와 포인터 선언//
int a=2;
int *p;
//변수와 포인터의 관계 설정//
p=&a;
//결과 출력//
printf("정수형의 크기는 %d바이트입니다\n",sizeof(int));//4//
printf("%d의 주소는 %d입니다\n",a,p);//주소값//
printf("%d의 값은 %d입니다\n",a,*p);//2//
printf("%d의 다음 주소 위치의 값은 %d입니다\n",a,*(p+1));//(p+1) 주소의 쓰레기값//
printf("%d의 다음 주소 위치의 주소값은 %d입니다\n",a,(p+1));//주소값+4//
//포인터 형 변환//
//char 자료형 포인터 선언 및 초기화//
//a=2는 2진수로 00000000 00000000 00000000 00000010//
char *p0;
p0=(char*)p;
//결과 출력//
printf("문자형의 크기는 %d바이트입니다\n",sizeof(char));//1//
printf("%d의 주소는 %d입니다\n",a,p0);//주소값(p)//
printf("%d의 값은 %d입니다\n",a,*p0);//a 값의 첫 번째 바이트 - 2//
printf("%d의 다음 주소 위치의 값은 %d입니다\n",a,*(p0+1));//a 값의 두 번째 바이트 - 0//
printf("%d의 다음 주소 위치의 주소값은 %d입니다\n",a,(p0+1));//주소값(p)+1//
}
실행 결과
정수형의 크기는 4바이트입니다 2의 주소는 6422028입니다 2의 값은 2입니다 2의 다음 주소 위치의 값은 10818512입니다 2의 다음 주소 위치의 주소값은 6422032입니다 문자형의 크기는 1바이트입니다 2의 주소는 6422028입니다 2의 값은 2입니다 2의 다음 주소 위치의 값은 0입니다 2의 다음 주소 위치의 주소값은 6422029입니다
프로그램 분석
이 예제 프로그램의 핵심 동작을 정리하면 다음과 같습니다.
정수형 포인터 p: sizeof(int)는 4바이트이므로, p+1을 하면 주소값이 4만큼 증가합니다(6422028 → 6422032). *(p+1)은 인접한 메모리 공간에 남아 있는 의미 없는 값(쓰레기값)을 출력합니다.
문자형 포인터 p0: int 포인터 p를 (char*)로 형 변환하여 만든 포인터입니다. sizeof(char)는 1바이트이므로, p0+1을 하면 주소값이 1만큼만 증가합니다(6422028 → 6422029).
바이트 단위 값 확인: a=2는 메모리에 리틀 엔디안 방식으로 저장되므로 첫 번째 바이트는 2, 두 번째 바이트는 0입니다. 따라서 *p0는 2를, *(p0+1)은 0을 출력합니다.
이처럼 포인터의 자료형에 따라 주소 연산 시 이동하는 바이트 크기가 달라지며, 형 변환을 활용하면 같은 메모리 공간을 다른 크기의 단위로 읽을 수 있다는 점을 이 예제를 통해 확인할 수 있습니다.