C/C++에서 배열 인덱스가 0부터 시작하는 이유
C/C++에서 배열의 인덱스가 왜 1이 아닌 0부터 시작하는지 궁금해한 적이 있을 것입니다. 그 답은 포인터 연산(pointer arithmetic)의 내부 동작 방식에 있습니다.
핵심 원리: arr[i]는 *(arr + i)와 같다
C/C++ 컴파일러는 배열 표기법 arr[i]를 항상 *(arr + i)로 해석합니다. 여기서 각 구성 요소의 의미는 다음과 같습니다.
arr은 배열의 첫 번째 요소, 즉 인덱스 0번 요소가 저장된 메모리 주소를 나타냅니다. 따라서 *(arr + i)는 '배열의 첫 번째 요소로부터 i만큼 떨어진 위치에 있는 요소'를 의미합니다.
여기서 중요한 점은 루프가 시작될 때 i의 초기값이 0이라는 것입니다. i가 0이면 *(arr + 0), 즉 배열의 첫 번째 요소 자신을 가리키게 됩니다. 바로 이 때문에 배열 인덱스는 0부터 시작하도록 설계된 것입니다.
예제 코드
다음 C++ 프로그램은 이 개념을 실제로 보여줍니다.
#include <iostream>
using namespace std;
int main() {
int arr[] = {5,8,9,3,5};
int i;
for(i = 0; i<5; i++)
cout<< arr[i] <<" ";
cout<<"\n";
for(i = 0; i<5; i++)
cout<< *(arr + i) <<" ";
return 0;
}
실행 결과
위 프로그램의 출력 결과는 다음과 같습니다.
5 8 9 3 5
5 8 9 3 5
코드 분석
위 프로그램의 동작을 단계별로 살펴보겠습니다.
배열 arr[]에는 총 5개의 정수 요소가 저장되어 있습니다. 프로그램은 두 개의 for 루프를 사용하여 첫 번째 루프에서는 일반적인 배열 표기법인 arr[i]로, 두 번째 루프에서는 포인터 연산 표기법인 *(arr + i)로 배열 요소들을 출력합니다.
두 방식 모두 완전히 동일한 결과를 출력합니다. 이는 arr[i]와 *(arr + i)가 컴파일러 내부에서 같은 의미로 처리된다는 사실을 명확하게 보여줍니다.
int arr[] = {5,8,9,3,5};
int i;
for(i = 0; i<5; i++)
cout<< arr[i] <<" ";
cout<<"\n";
for(i = 0; i<5; i++)
cout<< *(arr + i) <<" ";정리
결론적으로, 배열 이름 arr은 배열의 시작 주소를 가리키는 포인터 역할을 하며, 인덱스 i는 그 시작 지점으로부터 얼마나 떨어져 있는지를 나타내는 상대적 거리(offset)입니다. 시작 지점 자체는 거리가 0이므로, 배열 인덱스가 0부터 시작하는 것이 가장 자연스럽고 효율적인 설계인 것입니다.