C 언어에서 포인터(pointer)와 배열(array)은 대부분의 경우 서로 같은 것으로 취급됩니다. 실제로 배열 이름은 첫 번째 요소를 가리키는 주소처럼 동작하기 때문입니다. 하지만 두 개념 사이에는 중요한 차이점이 몇 가지 존재합니다.
1. &(주소) 연산자의 차이
&pointer: 포인터 변수 자체가 저장된 메모리 주소를 반환합니다.&array: 배열의 첫 번째 요소의 주소를 반환합니다.
2. sizeof 연산자의 차이
sizeof(array): 배열의 모든 요소가 차지하는 전체 메모리 크기를 반환합니다. 예를 들어 int형 요소 5개를 가진 배열이라면 일반적으로 20바이트(int가 4바이트일 때)를 반환합니다.sizeof(pointer): 포인터 변수 자체가 차지하는 메모리 크기만 반환합니다. 시스템 아키텍처에 따라 보통 4바이트 또는 8바이트입니다.
3. 값의 재할당 가능 여부
배열 변수는 한 번 선언되면 다른 주소를 가리키도록 값을 다시 할당할 수 없습니다. 반면 포인터 변수는 언제든지 다른 주소값을 저장하도록 변경할 수 있습니다.
선언 방법 비교
int a[]; // 배열 선언 int *p; // 포인터 선언
예제로 확인하는 차이점
정수형 포인터 변수가 하나 있다고 가정해 보겠습니다.
int *i;
이제 다음과 같은 할당문의 결과를 살펴보겠습니다.
a = &i; // 잘못된(illegal) 할당. 배열 변수는 갱신하거나 수정할 수 없습니다. p = &i; // 올바른(legal) 할당. 포인터는 새로운 주소값을 저장할 수 있습니다.
위 예제에서 볼 수 있듯이, 배열 이름은 수정 불가능한 상수 포인터(constant pointer)와 유사하게 동작하는 반면, 포인터 변수는 자유롭게 값을 변경할 수 있는 일반 변수입니다. 이러한 차이를 이해하면 C 언어에서 메모리를 더 안전하고 효율적으로 다룰 수 있습니다.