Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 배열의 인덱스가 0부터 시작하는 이유

배열은 본질적으로 메모리상의 특정 주소를 가리키는 포인터입니다. 이 주소가 바로 배열의 첫 번째 요소가 저장된 위치이며, 여기서 인덱스는 일종의 '오프셋(offset)', 즉 시작 지점으로부터 떨어진 거리를 의미합니다. 흥미롭게도 이 개념은 C 언어가 탄생하기 훨씬 이전부터 존재하던 원리입니다.

메모리 주소와 오프셋의 관계

예를 들어, 배열 요소가 메모리 주소 0Xff000에서 시작하고 {35, 23, 67, 88, 90}과 같은 5개의 요소를 가진다고 가정해 보겠습니다. int형 데이터는 4바이트로 저장되므로, 이 배열은 메모리에 다음과 같이 배치됩니다.

0Xff000 → 35
0Xff004 → 23
0Xff008 → 67
0Xff012 → 88
0Xff016 → 90

여기서 핵심은 다음과 같습니다. 배열에 접근할 때 오프셋이 0이면 곧 인덱스 0이 됩니다. 즉, 첫 번째 요소는 시작 주소에서 아무것도 더하지 않은 위치(거리 0)에 있으므로 자연스럽게 인덱스 0으로 접근하게 되는 것입니다. 실제로 컴파일러는 arr[i]라는 표현식을 시작주소 + i × 요소크기로 계산하기 때문에, 0부터 시작해야 포인터 연산이 단순하고 효율적입니다.

C#에서의 0 기반 인덱싱 개념

C# 역시 이 전통을 그대로 계승하여 배열의 인덱스를 0부터 시작합니다. 이를 정리하면 다음과 같습니다.

  • 배열이 비어 있으면 요소가 0개이며, 길이(length)도 0입니다.
  • 인덱스 0에 요소가 하나 있으면, 배열의 길이는 1입니다.
  • 인덱스 0과 1에 요소가 두 개 있으면, 배열의 길이는 2입니다.
  • 인덱스 0, 1, 2에 요소가 세 개 있으면, 배열의 길이는 3입니다.

즉, 배열의 길이는 항상 '마지막 인덱스 + 1'과 같습니다. 마지막 요소의 인덱스가 항상 length - 1이라는 점을 기억하면, 반복문 작성 시 범위 초과(IndexOutOfRangeException) 오류를 예방할 수 있습니다.

코드 예제

다음 코드는 C#의 배열이 인덱스 0부터 시작함을 보여주는 대표적인 예입니다.

/* 배열은 인덱스 0부터 시작 */
for (int i = 0; i < 10; i++) {
    num[i] = i + 10;
}

반복문이 i = 0에서 시작하여 i < 10 조건까지 실행되므로, 총 10개의 요소(인덱스 0~9)에 값이 할당됩니다. 만약 인덱스가 1부터 시작했다면 i <= 10처럼 조건을 수정해야 하고, 경계 검사 로직도 더욱 복잡해졌을 것입니다.

정리

C# 배열의 인덱스가 0부터 시작하는 이유는, 배열이 메모리 주소에 대한 참조이며 인덱스가 곧 시작 지점으로부터의 오프셋이기 때문입니다. 이러한 0 기반 인덱싱(zero-based indexing) 방식은 포인터 연산을 단순화하고, 메모리 접근을 효율적으로 만들어 주는 오랜 프로그래밍 전통이라고 할 수 있습니다.