배열은 왜 0부터 시작할까?

구준희·2024년 6월 19일

기본기

목록 보기
2/2

배열, 리스트를 사용할 때 인덱스 번호가 0번부터 시작해 헷갈리는 경우가 많이 생긴다.

예를 들어n*m 행렬을 그린다고 했을 때

//java
int[][] arr = new int[n][m];
//python
arr = [[0 for _ in range(m)] for _ in range(n)]

이렇게 선언해준다면 우측하단 좌표는 (n,m)이 아니라 (n-1,m-1)이 되어버린다.

왜 이렇게 불편하게 설정해 놓았을까?

우리가 변수 선언을 하면 메모리에 변수가 저장된다.

int a = 123;
// 메모리 어딘가에 12라는 값이 들어가 있음

어디에 저장된지 보고 싶으면 &라는 포인터연산자를 이용하면 그 변수의 메모리주소를 16진수로 반환한다.

int a = 123;
printf("%p\n", &a);

//결과
000000C2CDBAF534 //메모리주소값

Q. 그럼 메모리주소값만 알고 있으면 값을 알 수 있나요?

알수없다.

왜냐하면 저 주소는 정확하게 말하면 메모리의 시작주소이기 때문에 컴퓨터는 어디까지 불러야 할지 모르기 때문이다.

컴퓨터는 변수의 크기와 데이터 형식까지 알아야 비로소 해당 주소의 정확한 값을 해석할 수 있기 때문이다.


그러기 위해서는 포인터를 먼저 알아야 한다.

포인터란?

변수의 주소값을 저장하는 변수
즉, 포인터변수에는 다른 변수의 메모리 주소가 저장된다.

int a = 123; // 변수 a
int* p; // 포인터 변수 p
p = &a; // a의 메모리주소 값을 포인터변수 p에 저장

printf("%p\n", p);
printf("%d\n", &a);
출력결과
00000064C1CFFBA4
00000064C1CFFBA4

이렇게 포인터를 사용하면 변수의 주소값이 저장 가능하다.

이제 역참조연산자(derefrencing operator)를 사용해 포인터의 값을 불러오면 된다.

int a = 123;
int* p;
p = &a;
printf("%d\n", *p); // 역참조연산자 사용
printf("%d\n", a);

//결과 
123
123

포인터변수 pint*형으로 우리가 선언해주었다.
컴퓨터는 저 int*형을 통해서 메모리 주소 값에서 4byte만큼 읽으면 되는구나! 라는 걸 알게 된다.


Q. 이게 배열이 0번부터 시작하는거랑 뭔 상관인데요?

위에서 말했듯이 변수를 선언하면 컴퓨터 메모리 상에 해당 변수를 위한 공간이 할당되고, 변수 이름은 그 메모리 주소를 가리키게 된다.

그럼 배열은 어떻게 될까?

int arr[3] = {1,2,3};
printf("arr : %p\n", &arr);
printf("arr[0] : %p\n",&arr[0]);

// 출력결과
arr : 0000005D1E34F8E8
arr[0] : 0000005D1E34F8E8

Q. 왜 arr값이랑 arr[0]의 주소값이 같은거죠?

엄밀히 말하면 배열의 이름(arr)과, 첫번째의 주소값(arr[0])은 다른 것이지만 (sizeof로 둘의 크기를 비교하면 다른값이 나옴) c언어에서는 암묵적으로 첫 번째 원소를 가리키는 포인터로 타입변환이 되기 때문에 주소값이 같게 나온다.

[]연산자의 역할

사실 []얘는 연산자이다.

int arr[3] = { 1,2,3 };

printf("arr[2] : %d \n", arr[2]);
printf("*(arr+2) : %d \n", *(arr + 2));

// 출력 결과
arr[2] : 3
*(arr+2) : 3

컴퓨터는 []라는 연산자가 사용되게 되면 자동적으로 위와 같은 형태로 바꾸게 된다. 즉 우리가 아무생각없이 사용했었던 arr[2]가 사실은 *(arr + 2)라는 형태로 바뀌어서 처리가 되고 있던 것이다.
즉, 배열 이름에 인덱스를 더하는 것은 포인터 연산을 통해 해당 요소의 메모리 주소를 계산하는 것과 동일한 원리이다. 이를 통해 컴퓨터는 배열 요소에 빠르고 편리하게 접근할 수 있기 때문에 배열의 인덱스가 0으로 시작하게 되었다.

References
https://modoocode.com/23
https://modoocode.com/24
https://www.geeksforgeeks.org/why-array-index-starts-from-zero/

profile
꾸준히합니다.

0개의 댓글