포인터(Pointer)는 다른 변수의 메모리 주소를 저장하는 특수한 변수입니다. C 언어에서 포인터는 메모리를 직접 제어할 수 있게 해주는 핵심 기능으로, 효율적인 프로그래밍을 위해 반드시 이해해야 하는 개념입니다.
포인터의 주요 특징
메모리 공간 절약: 포인터를 활용하면 불필요한 데이터 복사 없이 주소만 전달할 수 있어 메모리를 효율적으로 사용합니다.
빠른 실행 속도: 메모리 위치에 직접 접근하기 때문에 간접 참조 없이 처리되어 실행 시간이 단축됩니다.
동적 메모리 관리: malloc(), free() 같은 함수와 함께 사용하여 메모리를 동적으로 할당하고 해제할 수 있습니다.
자료구조 구현: 연결 리스트, 트리, 그래프 등 다양한 자료구조를 구현하는 데 필수적으로 사용됩니다.
포인터와 2차원 배열의 관계
2차원 배열은 메모리상에서 행 우선(row-major) 방식으로 연속된 공간에 할당됩니다. 즉, 3×3 크기의 배열이라면 9개의 요소가 한 줄로 나란히 저장됩니다.
int a[3][3] = {1,2,3,4,5,6,7,8,9};


배열 요소의 주소 계산 방법
배열 이름 a가 시작 주소(예: 1234번지)를 가리킬 때, 특정 요소의 주소는 다음 공식으로 계산할 수 있습니다.
a[i][j] = *(시작주소 + i × 열의 개수 + j)
이 공식을 이용해 a[1][2]의 값을 구하는 과정은 다음과 같습니다.
a[1][2] = *(1234 + 1*3 + 2)
= *(1234 + 5)
= *(1234 + 5*4) // 4는 int형의 스케일 팩터(Scale Factor)
= *(1234 + 20)
= *(1254)
a[1][2] = 6
여기서 스케일 팩터(Scale Factor)란 자료형의 크기를 의미합니다. int형은 보통 4바이트이므로, 요소 5개만큼 떨어진 거리는 실제 바이트 주소로 20바이트가 됩니다.
예제 프로그램
다음은 포인터를 이용해 2차원 배열의 값을 입력받고 출력하는 C 프로그램입니다.
#include<stdio.h>
main ( ){
int a[3][3], i, j;
int *p;
clrscr ( );
printf ("Enter elements of 2D array");
for (i=0; i<3; i++){
for (j=0; j<3; j++){
scanf ("%d", &a[i][j]);
}
}
p = &a[0][0];
printf ("elements of 2d array are");
for (i=0; i<3; i++){
for (j=0; j<3; j++){
printf ("%d \t", *(p+i*3+j));
}
printf ("\n");
}
getch ( );
}
코드 설명
p = &a[0][0];— 배열의 첫 번째 요소 주소를 포인터 p에 저장합니다.*(p+i*3+j)— 포인터 산술 연산을 통해 2차원 배열의 (i, j) 위치 요소에 접근합니다. 여기서 3은 열의 개수입니다.
실행 결과
위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
enter elements of 2D array 1 2 3 4 5 6 7 8 9 Elements of 2D array are 1 2 3 4 5 6 7 8 9
이처럼 포인터를 활용하면 2차원 배열을 1차원 형태로 순회하면서도 원하는 위치의 값에 정확하게 접근할 수 있습니다. 포인터와 배열의 주소 계산 원리를 이해하면 C 언어의 메모리 구조를 더 깊이 파악할 수 있습니다.