C언어에서 배열 매개변수가 포인터로 취급되는 이유
C언어가 배열 매개변수를 포인터로 취급하는 가장 큰 이유는 실행 속도와 효율성입니다. 함수 호출 시 배열의 모든 요소를 하나씩 복사해서 전달하는 방법도 있지만, 이 방식은 배열의 크기가 클수록 시간과 메모리가 많이 소모되어 매우 비효율적입니다.
그래서 C언어는 배열의 첫 번째 요소 주소, 즉 기본 주소(base address)만 함수에 전달하는 방식을 사용합니다. 함수 내부에서는 이 포인터를 통해 배열의 나머지 요소들에 순차적으로 접근할 수 있습니다. 따라서 아래 두 함수 선언은 사실상 동일한 의미로 해석됩니다.
void fun(int a[]) {
...
}
void fun(int *a) { // 더 효율적인 방식
...
}C 컴파일러는 int a[] 형태의 매개변수를 자동으로 int *a, 즉 포인터로 변환(decay)하기 때문에 두 선언은 완전히 같습니다. 덕분에 대용량 배열이라도 주소값 하나만 넘기면 되므로 복사 오버헤드 없이 빠르게 동작합니다.
예제 코드
다음은 배열 표기법과 포인터 표기법, 두 가지 방식으로 배열 내용을 출력하는 C 프로그램입니다.
#include <stdio.h>
// 배열 표기법으로 배열 내용 출력
void display1(int a[])
{
int i;
printf("\nCurrent content of the array is: \n");
for(i = 0; i < 5; i++)
printf(" %d", a[i]);
}
// 포인터 표기법으로 배열 내용 출력
void display2(int *a)
{
int i;
printf("\nCurrent content of the array is: \n");
for(i = 0; i < 5; i++)
printf(" %d", *(a + i));
}
int main()
{
int a[5] = {4, 2, 7, 9, 6}; // 배열 요소 초기화
display1(a);
display2(a);
return 0;
}
실행 결과
Current content of the array is:
4 2 7 9 6
Current content of the array is:
4 2 7 9 6
display1()은 배열 표기법(a[i])을, display2()는 포인터 연산(*(a+i))을 사용했지만 실행 결과는 완전히 동일합니다. 이는 배열 이름이 함수의 인자로 전달될 때 자동으로 첫 번째 요소를 가리키는 포인터로 변환되기 때문입니다. 결국 C언어에서 배열을 함수에 전달한다는 것은 곧 포인터를 전달하는 것과 같습니다.