programing

인덱싱이 'C'에서 0으로 시작하는 이유는 무엇입니까?

copysource 2022. 10. 2. 15:35
반응형

인덱싱이 'C'에서 0으로 시작하는 이유는 무엇입니까?

어레이의 인덱스가 1이 아닌 C에서 0으로 시작하는 이유는 무엇입니까?

C에서 배열의 이름은 기본적으로 포인터(단, 주석 참조), 메모리 위치에 대한 참조, 그리고 식입니다.array[n]'의 위치'는 '기억의 위치'n시작 요소에서 멀리 떨어져 있습니다.이는 인덱스가 오프셋으로 사용됨을 의미합니다.의 첫 참조하는 되어 있기 에 (0 요소 있음) 어레이가 참조하는 메모리 위치에 포함되어 의 첫 번째 요소는 어레이가 참조하는 메모리 위치(0 요소 떨어져 있음)로 되어 있어야 합니다.array[0].

자세한 내용은 이쪽:

http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html

이 질문은 1년 전에 올라왔는데...


상기의 이유에 대해서

Dijkstra의 기사(이전에 삭제된 답변에서 참조)는 수학적 관점에서 타당하지만 프로그래밍에 관한 적절하지 않습니다.

언어 사양 및 컴파일러 설계자가 내린 결정은 컴퓨터 시스템 설계자가 0부터 시작하기로 결정한 것에 근거합니다.


생각할 수 있는 이유

대니 코헨의 '평화를 위한 탄원'을 인용했다.

임의의 베이스 b에 대해서, 최초의 b^N 비음수 정수는, 번호가 0부터 개시하는 경우에 한정해, 정확히 N자리(선행 0 포함)로 표시됩니다.

을 사용하다Base-2를 합니다.2^3 = 8'8번입니다.

  • 카운트 1부터 시작하면 8(표준: 1000)
  • 0부터 카운트를 시작하면 7(111개)

111 사용하여 수 3 비트,1000네 개


왜 이것이 관련이 있는가?

에는, 「」가 있습니다.2^N「」로 주소 셀.N 이제 1, 1로 2^N은 ""를 필요로 .N+1주소에 하기 합니다.1년 전,1년 후1000(일부러) 하는 또 다른 은 마지막 수 없는 로 두는 입니다.N어드레스 라인

둘 다 최적의 솔루션이 아닙니다.시작 카운트는 0으로 되어 있기 때문에 모든 주소에 액세스 할 수 있습니다.N★★★★★★★★★★★★★★★★★★!


결론

를 「」로 하는 :0그 후, 모든 디지털 시스템에 침투하고 있습니다.이것에 의해, 코드의 해석이, 기반이 되는 시스템이 해석할 수 있는 것으로의 변환이 용이하게 되기 때문입니다.그렇지 않으면 어레이 액세스마다 머신과 프로그래머 사이에 불필요한 변환 조작이 1개씩 발생합니다.컴파일이 쉬워집니다.


신문에서 인용한 내용:

여기에 이미지 설명 입력

0 기반 인덱스는 다음을 허용하기 때문에...

array[index]

...실시되는 것은...

*(array + index)

가 1과 같이.*(array + index - 1)

는 ★★★★★★★★★★★★★★★의addresselement열에있있 있있있다다하다

let arr = [10, 20, 40, 60]; 

은 '어드레스'라고 해 봅시다.12 and and of of of of of 의 사이즈element4 bytes.

address of arr[0] = 12 + (0 * 4) => 12
address of arr[1] = 12 + (1 * 4) => 16
address of arr[2] = 12 + (2 * 4) => 20
address of arr[3] = 12 + (3 * 4) => 24

그렇지 않다면 zero-based엄밀히 말하면, 델의 첫 번째 요소 주소입니다.array16위치가 잘못됐기 때문에12.

0은 어레이의 선두에 대한 포인터에서 어레이의 첫 번째 요소까지의 거리입니다.

고려사항:

int foo[5] = {1,2,3,4,5};

0에 액세스하려면 다음 작업을 수행합니다.

foo[0] 

그러나 foo는 포인터로 분해되며, 위의 접근은 포인터 산술적으로 접근합니다.

*(foo + 0)

요즘은 포인터 산수가 잘 안 쓰이거든요.옛날에는, 주소를 받아, 그 시작점에서 X 「ints」를 떼어낼 수 있는 편리한 방법이었습니다.물론 그대로 있으려면 0을 더하면 됩니다!

같은 이유로 수요일까지 몇 일냐고 물으면1이 아니라0이라고 대답하고목요일까지 몇 일냐고 물으면2가 아니라1이라고 대답합니다

저는 자바 출신입니다.나는 이 질문에 대한 답을 아래 그림에서 제시했는데, 그것은 내가 스스로 설명할 수 있는 종이에 쓴 것이다.

주요 절차:

  1. 참조 작성
  2. 어레이 인스턴스화
  3. 어레이에 데이터 할당

  • 또, 어레이가 인스턴스화된 시점도 주의해 주세요.기본적으로는 값을 할당할 때까지 모든 블록에 0이 할당됩니다.
  • 첫 번째 주소가 참조를 가리키므로 어레이가 0으로 시작됩니다(이미지에서는 i:e - X102+0).

여기에 이미지 설명 입력

주의: 이미지에 표시된 블록은 메모리를 나타냅니다.

컴파일러와 링커를 심플하게(작성하기 쉽게) 했기 때문입니다.

레퍼런스:

"주소와 오프셋으로 메모리를 참조하는 것은 거의 모든 컴퓨터 아키텍처에서 하드웨어에 직접 나타나기 때문에 C의 설계 세부사항을 통해 컴파일이 쉬워집니다."

그리고.

"...이것에 의해, 실장이 심플해집니다.."

배열에서 인덱스는 시작 요소로부터의 거리를 나타냅니다.따라서 첫 번째 요소는 시작 요소에서0 거리에 있습니다.따라서 어레이는 0부터 시작합니다.

0으로 하다2000년, 이제arr[i] = *(arr+i), 이제if i= 0은 ,을 의미합니다.*(2000+0는 배열 의 첫 또는 으로 취급되므로 합니다.이 인덱스는 오프셋으로 처리되므로 bydeafault 인덱스는 0부터 시작됩니다.

가 5인 배열을 가정해 .
array [ = [, 8 array [ 5 ]= [ 2, 3, 5, 9, 8 ]

의 첫 .

인덱스는 0부터가 아니라 1부터 시작하는 것으로 합니다.

, 그럼 이제 첫을 받아 .
번째 (100입니다.)

에 4비트이기
때 그 는 > > > > > > > > > > > > > > > > > > > > > > > >>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
index의* 4)의= 4의 크기 (1) * 4의 크기 = 4의
실제 는 ' 위치'가 됩니다.

+ 4= + 4 = 104

최초 위치가 100이었기 때문에 사실이 아닙니다.
.
은 틀렸다

, 이제 0에서요. 0에서 지수를 가져왔습니다.

첫 번째 요소의 위치는 다음과 같아야 합니다.
크기(0(4)= 0 인스(0) * 0 크크(4) = 0

외부 -->
+ 0=이면 100 + 0 = 100이면 100입니다.

였습니다.
어울리면 0;어울리면 0으로 시작합니다.

이것으로 요점이 명확해졌으면 합니다.

1 베이스 매트릭스상의 X, Y 좌표를 사용해 픽셀 화면에 액세스 합니다.그 공식은 완전히 복잡하다.왜 복잡한가?X,Y 좌표를 간격띄우기라는 하나의 숫자로 변환하기 때문입니다.왜 X,Y를 오프셋으로 변환해야 하죠?메모리 셀(어레이)의 연속적인 스트림으로서 컴퓨터 내부에서 메모리가 그렇게 구성되어 있기 때문입니다.컴퓨터는 어레이 셀을 어떻게 취급합니까?오프셋 사용(첫 번째 셀에서의 배치, 제로 기반 인덱싱 모델).

코드의 어느 시점에서는, 1 베이스의 수식을 0 베이스의 수식으로 변환할 필요가 있습니다.컴퓨터는 메모리를 그렇게 취급하기 때문입니다.

기술적 이유는 어레이의 메모리 위치에 대한 포인터가 어레이의 첫 번째 요소의 내용이라는 사실에서 비롯될 수 있습니다.인덱스가 1인 포인터를 선언하면 프로그램은 보통 포인터에 값 1을 추가하여 원하는 콘텐츠에 액세스합니다.

제가 읽은 제로베이스 번호부여에 대한 가장 우아한 설명은 값이 숫자선의 표시된 위치에 저장되는 것이 아니라 그 사이의 공간에 저장된다는 것입니다.첫 번째 항목은 0과 1 사이에, 다음 항목은 1과 2 사이에 저장됩니다.N번째 항목은 N-1과 N 사이에 저장됩니다. 다양한 항목은 양쪽의 숫자를 사용하여 설명할 수 있습니다.개별 품목은 아래의 숫자를 사용하여 기술된 관례에 따라 지정됩니다.범위(X,Y)가 주어진 경우 아래 숫자를 사용하여 개별 번호를 식별하면 산술(X 항목)을 사용하지 않고도 첫 번째 항목을 식별할 수 있지만 마지막 항목(Y-1)을 식별하려면 Y에서 하나를 빼야 합니다.위의 숫자를 사용하여 항목을 식별하면 범위 내의 마지막 항목(항목 Y)을 식별하기가 쉬워지지만 첫 번째 항목(X+1)을 식별하기는 어렵다.

위의 숫자를 기준으로 항목을 식별하는 것은 나쁘지 않지만, 일반적으로 X 위의 항목(X, Y)을 아래 항목(X+1)으로 정의하는 것보다 더 잘 작동합니다.

우선 어레이는 내부적으로 포인터로 간주된다는 것을 알아야 합니다.왜냐하면 어레이 이름 자체가 어레이의 첫 번째 요소의 주소를 포함하고 있기 때문입니다.

ex. int arr[2] = {5,4};

어레이가 주소 100에서 시작되므로 요소 첫 번째 요소는 주소 100에서 시작되며 두 번째 요소는 현재 104에서 시작된다고 가정합니다. 어레이 인덱스가 1에서 시작되므로

arr[1]:-

포인터 표현으로 이렇게 쓸 수 있어요.

 arr[1] = *(arr + 1 * (size of single element of array));

현재 int 사이즈는 4바이트입니다.

arr[1] = *(arr + 1 * (4) );
arr[1] = *(arr + 4);

어레이 이름에는 첫 번째 요소의 주소가 포함되어 있으므로 arr = 100,

arr[1] = *(100 + 4);
arr[1] = *(104);

그러면

arr[1] = 4;

이 표현 때문에 공식 첫 번째 요소인 주소 100의 요소에 액세스할 수 없습니다.

이제 어레이 인덱스가 0부터 시작한다고 가정해 보겠습니다.

arr[0]:-

이 문제는 다음과 같이 해결됩니다.

arr[0] = *(arr + 0 + (size of type of array));
arr[0] = *(arr + 0 * 4);
arr[0] = *(arr + 0);
arr[0] = *(arr);

어레이 이름에는 첫 번째 요소의 주소가 포함되어 있기 때문에

arr[0] = *(100);

올바른 결과를 얻을 수 있습니다.

arr[0] = 5;

따라서 어레이 인덱스는 항상 0(c)부터 시작합니다.

참조: 모든 세부 사항은 책 "브라이언 키닝한과 데니스 리치의 C 프로그래밍 언어"로 쓰여 있습니다.

어레이 이름은 기본 주소를 가리키는 상수 포인터입니다.arr[i]를 사용하면 컴파일러는 *(arr+i)로 처리합니다.int 범위는 -128 ~127이므로 컴파일러는 -128 ~-1은 음수이고 0 ~128은 양수라고 생각합니다.따라서 어레이 인덱스는 항상 0으로 시작합니다.

언급URL : https://stackoverflow.com/questions/7320686/why-does-the-indexing-start-with-zero-in-c

반응형