C 프로그래밍을 배우다 보면 포인터(pointer)와 배열(array)은 반드시 이해해야 하는 핵심 개념입니다. 두 개념은 메모리와 밀접한 관련이 있지만, 그 역할과 동작 방식에는 분명한 차이가 있습니다. 이 글에서는 포인터와 배열의 정의, 선언 방법, 예제 코드를 통해 두 개념의 차이점을 명확하게 살펴보겠습니다.
포인터(Pointer)란?
포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 어떤 변수에 메모리가 할당되면, 포인터는 그 변수가 위치한 메모리 주소를 가리키게 됩니다. 포인터 변수를 선언할 때는 단항 연산자인 별표(*)를 사용합니다.
포인터 선언 문법
datatype *variable_name;
여기서 datatype은 int, char, float 등 변수의 자료형을 의미하며, variable_name은 사용자가 지정하는 포인터 변수의 이름입니다.
포인터 예제 코드
다음은 포인터의 동작을 보여주는 C 프로그램입니다.
#include <stdio.h>
int main () {
int a = 8;
int *ptr;
ptr = &a;
printf("Value of variable a: %d\n", a);
printf("Address of variable a: %d\n", ptr);
return 0;
}위 프로그램의 실행 결과는 다음과 같습니다.
Value of variable a: 8 Address of variable a: -2018153420
실행 결과에서 볼 수 있듯이, 변수 a에는 값 8이 저장되어 있고, 포인터 ptr에는 변수 a의 메모리 주소가 저장되어 있습니다. 참고로 주소 값은 실행 환경마다 매번 달라질 수 있습니다.
배열(Array)란?
배열은 같은 자료형의 요소들을 연속된 메모리 공간에 저장하는 자료 구조입니다. 배열에서 가장 낮은 주소는 첫 번째 요소에 해당하고, 가장 높은 주소는 마지막 요소에 해당합니다. 또한 배열의 인덱스는 0부터 시작하여 (배열 크기 - 1)까지 이어집니다.
배열 선언 문법
type array_name[array_size];
여기서 array_name은 배열의 이름이며, array_size는 배열의 크기를 나타냅니다.
배열 예제 코드
다음은 배열의 동작을 보여주는 C 프로그램입니다.
#include <stdio.h>
int main () {
int a[5];
int i,j;
for (i = 0;i<5;i++) {
a[i] = i+100;
}
for (j = 0;j<5;j++) {
printf("Element[%d] = %d\n", j, a[j] );
}
return 0;
}위 프로그램의 실행 결과는 다음과 같습니다.
Element[0] = 100 Element[1] = 101 Element[2] = 102 Element[3] = 103 Element[4] = 104
예제에서 크기가 5인 int형 배열 a를 선언한 뒤, 각 요소에 100부터 104까지의 값을 순서대로 저장하고 출력했습니다. 인덱스가 0부터 시작한다는 점에 유의하세요.
포인터와 배열의 핵심 차이점
두 개념을 비교하면 다음과 같은 차이가 있습니다.
- 저장하는 값: 포인터는 다른 변수의 메모리 주소를 저장하지만, 배열은 같은 자료형의 실제 데이터 값들을 연속된 메모리에 저장합니다.
- 크기 변경: 포인터는 가리키는 대상을 얼마든지 변경할 수 있는 반면, 배열은 한 번 선언하면 크기를 변경할 수 없습니다.
- 메모리 할당: 배열은 선언 시 고정된 크기의 메모리가 할당되지만, 포인터는 동적 메모리 할당(malloc 등)과 함께 유연하게 활용될 수 있습니다.
- 증감 연산: 포인터 변수는 증감 연산(++, --)으로 주소를 이동할 수 있지만, 배열 이름은 상수처럼 취급되어 수정할 수 없습니다.
이처럼 포인터와 배열은 서로 밀접하게 연관되어 있지만, 목적과 동작 방식이 다르기 때문에 각각의 특성을 정확히 이해하고 사용하는 것이 중요합니다.