컴퓨터는 왜 0부터 계산합니까?


55

컴퓨터는 전통적으로 0부터 시작하여 숫자 값을 집계합니다. 예를 들어 C 기반 프로그래밍 언어의 배열은 인덱스 0에서 시작합니다.

이것에 대한 역사적인 이유는 무엇이며, 0부터 계산하는 것이 실질적인 이점은 1에서 계산하는 것보다 큽니까?

참고 : 이 질문은 단순한 의견이 아니라 잘 설명 된 기술 답변을 요구하며 프로그래밍이 아닌 일반적인 컴퓨터를 다루기위한 것입니다. 이 질문은 프로그래머의 질문 "왜 구조체 / 배열은 0 기반입니까?" .



9
1- 원점 배열을 사용한 컴퓨터 언어의 예는 몇 가지가 넘습니다.
Daniel R은

23
인간은 왜 0부터 계산하지 않습니까?
제목 없음

47
Wahah, Wah, 아무도 0에서 세지 않고 우리는 0에서 색인 합니다. 아무도 "제로"요소를 말하지 않습니다. 우리는 인덱스 0 에서 "첫번째"요소를 말합니다. 인덱스가 요소가 첫 번째 위치에서 얼마나 멀리 떨어져 있는지 생각하십시오. 첫 번째 요소는 첫 번째 위치에 있으므로 전혀 오프셋되지 않으므로 인덱스는 0입니다. 두 번째 요소는 이전의 한 요소이므로 오프셋 1 요소이며 인덱스 1에 있습니다.
mowwwalker

14
@Ramhound 아니오, 그렇지 않습니다. 0부터 시작하는 인덱싱은 이진 사용과 전혀 관련이 없습니다.
피터 올슨

답변:


88

0부터 배열을 계산하면 각 요소의 메모리 주소 계산이 간단 해집니다.

배열이 메모리의 지정된 위치에 저장되면 (주소라고 함) 각 요소의 위치는 다음과 같이 계산 될 수 있습니다.

element(n) = address + n * size_of_the_element

첫 번째 요소를 첫 번째 요소로 생각하면 계산은

element(n) = address + (n-1) * size_of_the_element

큰 차이는 아니지만 각 액세스에 대해 불필요한 빼기를 추가합니다.

편집하다

  • 배열 인덱스를 오프셋으로 사용하는 것은 요구 사항이 아니라 습관입니다. 첫 번째 요소의 오프셋은 시스템에 의해 숨겨지고 요소를 할당하고 참조 할 때 고려 될 수 있습니다.

  • Dijkstra 는 "0으로 시작해야하는 이유"( pdf )를 발간하여 0으로 시작하는 것이 더 나은 선택 인 이유를 설명합니다. 0에서 시작하면 범위를 더 잘 표현할 수 있습니다.


8
정답은 +1입니다. 0 기반 색인은 사용되는 언어 의 (매우 일반적인) 규칙입니다. 보편적이지 않습니다. 예를 들어 Lua는 1 기반 인덱싱을 사용합니다 . "불필요한 빼기"는 예전에는 0부터 시작하는 인덱싱의 원인이되었을 수도 있지만 이제는 대부분의 언어가 모든 사람들이 이미 익숙한 것 (대부분 C 덕분에) 이기 때문에이를 사용합니다. 협약.
BlueRaja-대니 Pflughoeft

2
이것은 말이되지 않습니다. address + n * size_of_element"주소"가 0 번째 요소의 주소 인 한 각 요소의 위치는 항상 계산할 수 있습니다 . 이것은 0 번째 요소가 배열의 요소로 존재하는지 여부에 관계없이 완벽하게 작동합니다. 문제는 왜 제로 요소가 존재하는지, 왜 우리가 주소를 (명 목적) 제로 요소의 주소로 저장하는지가 아닙니다. (이 답변이 있습니다.)
David Schwartz

3
@DavidSchwartz C로 오래된 언어를 봅시다 . 메모리를 할당하면 메모리가 시작되는 주소를 얻습니다. 컴파일러가 무언가를 본다면 v[n]식의 주소를 계산해야합니다. 인덱스가 0을 시작하면 계산은 v + x * size입니다. 1에서 계산은 v + (x-1) * size입니다. 예를 들어, v [1]은 v + (1-1) * v에 해당합니다.
Matteo

4
@David : C (실제로 0 기반 인덱싱을 대중화 한 언어) 에서 배열과 포인터는 대체로 교환이 가능하므로 *array실제로 첫 번째 요소 를 나타내는 여러 가지 이유로 중요합니다 . 예를 들어 , 첫 번째 요소 이전array 의 메모리 위치 가리키면 다른 유형의 배열로 캐스트하는 것이 번거로울 수 있습니다. ints 배열에서 두 번째 바이트의 위치 는 워드 크기에 따라 달라집니다. 32 비트 시스템에서는 ((char*)intArray + 5)!!
BlueRaja-대니 Pflughoeft

3
아니요, 배열에 0 번째 요소가 있는지 여부는 문제가되지 않습니다. 보시다시피 스케일링도 있습니다. 8 바이트 객체의 배열이 있고이를 바이트 배열로 오버레이하면 객체의 바이트 인덱스는 무엇입니까? 왜 간단한가 : 42 * 8. 1 기반의 문제는 바이트 배열을 볼 때 1의 오프셋이 1 바이트이고, 중첩 된 8 바이트 단위 배열을 볼 때 8 바이트라는 것입니다.
Kaz

38

아래의 원칙은 다른 모든 10 진수에도 적용되지만 컴퓨터에서 0부터 계산은 컴퓨터에서 사용되는 숫자를 나타내는 고정 자리 이진 시스템에서 자연스럽게 쉽게 이해할 수 있습니다. 8 비트가있는 경우 표현할 수있는 1과 0의 256 가지 가능한 조합이 있습니다. 이 8 비트를 사용하여 1-256의 숫자를 표현할 수 있지만 0은 수학 자체에서 숫자로 유용한 0을 생략하므로 숫자 0-255를 표현하는 데 사용됩니다.

이것은 이미 0 (2 진 표현의 모든 0)에서 255 (8 비트 숫자의 모든 1)로 시작하는 자연 순서의 선례를 설정합니다. 숫자를 나타내는 시스템을 고려할 때 0은 시스템의 "첫 번째"숫자이므로 1은 "두 번째"숫자이므로 0부터 시작하는 것이 좋습니다.

컴퓨터에서 0부터 시작하는 것이 편리한 이유는 오프셋 개념 때문입니다. 오프셋은 메모리 또는 하드 디스크 또는 다른 "주소 지정 가능"매체의 위치로부터의 거리를 나타내는 숫자입니다. 컴퓨터에서는 실제로 모든 데이터가 선형으로 저장되므로 데이터 순서, 첫 번째 바이트, 두 번째 바이트 등이 있습니다. 오프셋을 통해 데이터의 "영역"의 위치를 ​​표현하는 것이 편리합니다. 데이터 블록의 첫 번째 바이트는 무엇입니까? 오프셋 '0'에 있습니다. 즉, 데이터 블록에서 첫 번째 바이트 다음에 0 바이트가 발견됩니다. "1"이 첫 번째 바이트를 지정할 수는 있지만 몇 가지 이유로 인해 데이터를 표현할 때 복잡성이 발생합니다.

  • 데이터 주소 지정에 0을 사용하지 않으면 8 비트 숫자로 지정할 수있는 항목 수가 하나씩 줄어 듭니다.
  • 하드웨어 수준의 데이터 액세스에 필요한 오프셋을 계산하려면 어느 시점에서 번호 매기기에서 하나를 빼야하므로 복잡성이 발생합니다.
  • 데이터 블록에 대한 포인터는 항상 첫 번째 블록을 가리 키므로 0부터 시작할 때 산술이 간단합니다. 즉, 첫 번째 데이터 클러스터의 첫 번째 블록에서 첫 번째 바이트는 0에서 시작하면 0 + 0 + 0입니다. , 1에서 시작할 때 1 + 1 + 1-1 -1입니다.)이 예와 같이 중첩 된 데이터 구조로 1에서 시작할 때의 산술은 혼동 될 수 있습니다.

31
이진 표현과 관련이 없습니다. 이진수와 십진수는 모두 0부터 시작합니다.
Matteo

2
0부터 계산을 시작하면 (이론적으로) 1에서 257로 갈 수있는 주소의 수를 줄이지 않습니다.
Matteo

6
@Matteo는 당신이 할 수 없었던 단일 바이트가 아닙니다
OrangeDog

8
@Dougvj Zero-based counting은 바이너리와 전혀 관련이 없습니다 . 요점은 고정 숫자로 된 모든 숫자를 사용하는 것입니다. 이는 2 진수, 10 진수 또는 23517을 사용하는지 여부에 관계없이 문제가됩니다.
Peter Olson

2
-1 이진 표현과는 전혀 관련이 없습니다.
BlueRaja-대니 Pflughoeft

26

나와 같은 안락 의자 철학자에게는 수퍼 유저가 등장 할 것이라고 생각하지 않았습니다. 비 철학자들은 세부적인 내용을 건너 뛰는 경향이 있기 때문에 여기에는 근본적인 오해가 있습니다. 한마디로 : 컴퓨터는 0부터 세지 않지만 위치 명칭은 0부터 시작합니다.

컴퓨터와 사람의 계산 기술 사이의 이러한 불일치에 대해 혼동되지 않습니다. 질문을 분해하자.

컴퓨터는 왜 0부터 계산합니까?

  • 그들은 0에서 계산하지 않습니다

컴퓨터 집계 값은 0부터 시작합니다. 예를 들어 C의 배열

  • 인덱스 (위치 표시기 탈리)은 0부터 시작한다. 카운트 단일 요소 인덱스가 배열의 요소들은 제로

영은 무언가의 공극 또는 스케일의 중간 지점을 나타내는 데 실용적입니다. 0을 정의하면 불가능하기 때문에 계산에 실용적이지 않습니다 .

스케일의 중간 점과 같은 의미에서, 0은 컬렉션의 가장 가장자리 (절대 시작)를 나타내는 데 사용될 수 있습니다. 이 질문은 "tally values"와 "count from zero"간에 일치하지 않기 때문에 의미가 없습니다.

예, 컴퓨터는 0부터 집계하지만 1부터 계산합니다. 두 단어는 다른 의미를 지닙니다.

탈리 [tal-ee]

명사

  1. 계정 또는 계산; 직불 및 신용 기록, 게임 점수 등.
  2. 점수 나 계정이 유지되는 모든 것 ..
  3. 기록 된 항목의 수 또는 그룹.

카운트 [쿠트]

동사 (객체와 함께 사용)

  1. 총 수를 결정하기 위해 하나씩 (컬렉션의 개별 단위 또는 그룹) 점검합니다. 합산; 열거 : 그는 티켓을 세고 열 마리를 가지고 있음을 알았습니다.
  2. 생각하기 위해; 계산하다; 계산합니다.
  3. 눈을 감고 10을 세십시오.

(dictionary.com)


실용적인 이유는 Dougvj에 의해 적절하게 설명되어 있습니다. 60 세의 CS 교수에게 역사적인 설명을 해줄 수 있다면 ...


실제로 컴퓨터가 어디에서 시작하는지 어떻게 알 수 있습니까? 당신이 그것을 아는 것은, 그것을 사용할 때, 당신은 그것을 0에서 시작한다고 말합니다.
Daniel R은

여기서는 컴퓨터 자체의 작동 방식이 아니라 개념과 논리의 정의에 대해 이야기하고 있습니다. CS 과정을 수강했기 때문에 컴퓨터가 어디에서 시작하는지에 대해 조금 알고 있습니다.
Ярослав Рахматуллин

1
완전히 pedantic하기 위해 동사를 명사와 비교합니다. "tally"와 "count"는 실제로는 동의어이며 둘 다 동사 나 명사로 사용될 수 있습니다.
Brian

1
@ 브라이언 (Brian) 공정한 관찰과 나의 의도는 혼동이 용어의 오해로부터 비롯된 것을 (페데 닉 방식으로) 설명하는 것이다. "첫 번째 요소"와 "0 위치의 요소"사이에는 실제로 차이가 없습니다. 둘 다 요소 하나입니다. 첫째 ,하지 " 영차 ". 0부터 계산하는 것은 없습니다 . 주소 지정은 a-> 1, b-> 2 일 수 있지만, 열거는 정의 에 따라 하나씩 시작됩니다 . c-> 3 또는 0-> 1, 1-> 2, 2-> 3. "0에서 계산"의 가장 일반적인 예는 중학교 수학 서적에서 {x₀, x₁, x₂} 형식으로 찾을 수 있지만 아래 첨자는 색인 입니다.

1
디자이너가 현재 계획에 정착하기 전에 실제로 방황했다는 것입니다. "명백한"것은 지금은 아니었다. 아마도 다소 다른 계획이 선택되었을 수 있으며 이제 우리가 가진 것보다 더 "분명한"것처럼 보일 것입니다.
Daniel R Hicks

12

나는 이것이 " prof.dr. Edsger W. Dijkstra " -1982 년 8 월 11 일자 서한에있는 Burroughs Research Fellow에 의해 다루어 졌다고 생각한다 : cf EWD831

제목 : 번호는 0에서 시작해야하는 이유 . "한 규칙을 다른 규칙보다 선호하는 이유가 있습니까? 네, 있습니다."

Dijkstra는 1968 년까지 ALGOL 68 설계 팀 에있었습니다 . Algol68은 0, 1 또는 프로그래머가 알고리즘에 적합한 것으로 간주하는 임의의 수의 배열을 허용합니다. cf ( "The Algol 68 만들기" 는 "삼각 배열을 정의 할 수 있습니까?"라고 누군가 (토니 호 아어?)가 중단했습니다.

특히 Algol68에서는 배열 (& 행렬)이 슬라이스 될 때 인덱스 @ 1을 얻으므로 [1 : ...] 배열에 대한 편향이 있습니다. 그러나, "1 " 하한이 시작되도록 이동 될 수있다 "0 " 매트릭스의 Y [4 : 99 : 99 1,4- @ 예 벡터의 X [2 @ 99 (4)], "@ 0"을 지정하여 위치 @ 0]. 유사의 기본 / 바이어스가 에서 1 할 일이 ~ OD 루프 ( "하지 않는 한 에서 , 그리고 정수 1에서 0"으로 명시되어있다) 경우에서 ~, ~, ~ ESAC C (그리고 $ ~, ~, ~ ) $ 선택 조항.

1968 년 3 월 초안 보고서 ( MR93 ) 에 대한 Dijkstra의 의견 과 그의 주장은 아마도 유즈넷 이전의 화염 전쟁을 일으켰다 . "문법적이지 않더라도 좋아할만한 글이 있고, 매우 문법적이지만 다른 글이있다. 역겨워 요. 이것은 피상적 인 사람들에게 설명 할 수없는 것입니다. " EWD230

Algol 68 최종 보고서 (FR)는 1968 년 12 월 20 일 뮌헨 회의에서 다시 발표 된 후 실무 그룹에 의해 채택되었습니다. 그 후이 보고서는 유네스코 IFIP 총회에서 승인을 위해 승인되었습니다 .

12 월 23 일 (?) 1968 년 Dijkstra, Duncan, Garwick, Hoare , Randell , Seegmuller, Turski, Woodger 및 Garwick은 AB31.1.1.1 "소수자 보고서", 7 페이지 (1970 년 발행)에 서명했습니다 .


10

다른 사람이 가져온 거리 비유는 매우 실용적인 예를 제시합니다.

"가장 가까운 주유소에서 얼마나 떨어져 있습니까?"

"1 마일"

"주유소에 살아요?"

"아니요, 주유소에 살면 0 마일이됩니다"

"왜 1이 아닌 0에서 세고 있습니까?"

또 다른 좋은 예는 생일입니다. 우리는 누군가가 태어난 날 1 살이라고 말하지 않으며 1 년 후라고 말합니다.

2000 년 , 2001 년, 2002 년, 2003 년, 2004 년 은 5 년 이지만 윤년이나 미국 대통령 선거는 4 년마다 한 번씩이라고합니다 . (우연히도, 로마인들은 이것을 잠시 망쳐 놓았고, 수년이 너무 가까웠습니다)

내 요점은, 우리는 현실 세계에서 항상 0부터 "계산"한다- "[배열의 시작] 이후에 원하는 요소가 얼마나 많은 위치"는 단순히 0에서 카운트로 대답하는 질문 일 뿐이다. 많은 컴퓨터 프로그램에서. 첫 번째 요소가 시작 한 위치라고 말하지 않습니까? 그것은 이다 시작.


1
선거에 관한 당신의 수학은 1 년이 지났습니다. 귀하의 예에는 5 년 동안 2 년의 선거 기간이 포함됩니다. 올바른 예는 한 선거에서 다음 선거로 4 년이 지나는 것, 즉 2000-> 2001 (1 년), 2001-> 2002, 2002-> 2003, 2003-> 2004입니다.
Jimmy

1
@Jimmy 그것은 내 요점 이었다. 만약 사람들이 컴퓨터를 원한다는 의미에서 "하나에서 계산"한다면, 2000은 0이 아니라 1로 계산 될 것이다. 이것은 우연히, 고대 로마인들이 실제로 한 일입니다 (실제로 "2000, 2004, 2008"과 같은주기를 5 년 주기로 묘사합니다).
Random832

2
당신의 생일 예는 보편적으로 사실이 아닙니다. 예를 들어, 대한민국의 첫해는 0 대신 1로 계산됩니다 .
BennyMcBenBen

6

다른 사람들이 이미 말했듯이 컴퓨터는 0부터 계산하지 않습니다 .

일부 언어는 0에서 색인화합니다. 0에서 색인화하면 두 가지 주요 이점이 있습니다.

  1. 포인터에서 첫 번째 위치까지의 오프셋으로 해석 될 수 있으므로 자연스러운 방식으로 어셈블리로 변환됩니다.

  2. 네거티브를 원할 때 이상하지 않습니다. 1BC와 1AD 사이에 몇 년이 걸립니까? 없음 BC는 사실상 음수 날짜이지만 연도는 없습니다. 0AD가 있었다면 여기서 아무런 문제가 없을 것입니다. 과학에서 사람들이 첫 번째 요소를 순진하게 +1로 정의한 동일한 문제가 있습니다.


그렇습니다. 2001 년까지 새로운 밀레니엄을 기다리는 모든 어리 석음. 이것은 프로그래밍에 어려움을 겪을 때 제로 기반 배열을 "얻지"않는 사람들을 혼란스럽게합니다. :)
Kaz

3
또한 "1 마일"이 "바로 여기"를 의미하는 경우, 1 마일이 1760 피트이므로 "1760 피트"도 "바로 여기"를 의미합니다. 잘못된, "1 피트"는 바로 여기서 의미합니다. 이 하나의 기반 어리 석음에서 "바로 여기"는 1 피트, 1 인치, 1 센티미터 등입니다.
Kaz

1
@kaz 여기서 피트 => 야드. 1 마일에 1760 야드.
Brad

3

자연스럽게 계산은 0에서 시작합니다

바구니에 사과를 세는 알고리즘은 다음과 같습니다.

count := 0

for each apple in basket
   count := count + 1

위의 실행 후 count사과 수를 보유합니다. 바구니가 비어있을 수 있으므로 0 일 수 있습니다.

한 달 동안 신용 카드를 사용하지 않으면 1 달러의 청구서가 있습니까? 아니면 1 센트?

자동차 주행 거리계에서 트립 미터를 재설정하면 0001 또는 0000으로 이동합니까?

배열은 동일한 데이터에 대한 여러 뷰를 제공 할 수 있습니다

d각각 16 비트 워드로 구성된 32 비트 구조의 배열을 고려하십시오 w. 각 워드는 2 개의 8 비트 바이트로 구성 b됩니다. 제로 인덱싱에서 오버레이는 매우 편리하게 보입니다.

d: |   0   |   1   |
w: | 0 | 1 | 2 | 3 |
b: |0|1|2|3|4|5|6|7|

32 비트 객체 d[1]워드 주소로서 w[2]용이 32, 16 비트의 객체의 크기의 비율을 2로 인덱스를 곱하여 계산된다. 또한 바이트 주소 지정에서는입니다 b[4].

바이트, 워드, 더블 워드 등 모든 측정 단위에서 0이 0이기 때문에 작동합니다.

위의 다이어그램을보십시오. 단위 변환이 직관적 인 눈금자와 매우 유사합니다.

하나의 기반 인덱싱으로 다음이 깨집니다.

d: |   1   |   2   |
w: | 1 | 2 | 3 | 4 |
b: |1|2|3|4|5|6|7|8|

이제 d인덱스를 얻기 위해 인덱스에 2를 곱하거나 인덱스를 얻기 위해 w4를 곱할 수 없습니다 b. 단위 간 변환이 어색해집니다. 인스턴스에서 이동의 경우 d[2]b[4], 우리는 계산해야합니다 ((2 - 1) * 4) + 1 = 5.

d단위 에서 성가신 1 바이어스를 빼고 자연 0 기반 좌표계에서 스케일링을 한 다음 성가신 1을 b단위로 다시 추가해야합니다 . 동일하지 않습니다 1! 우리는 하나의 더블 워드 너비를 빼고 1 바이트 너비를 더 합니다.

데이터의 다른 뷰 간 변환은 섭씨-화씨 변환과 유사합니다.

1 기반 배열은 구현 수준에서 다루기가 쉽다고 말하는 사람들은 1을 간단히 빼면 스스로를 속이고 있기 때문입니다. 다른 데이터 유형간에 스케일링 계산을 수행하지 않는 경우에만 해당됩니다. 이러한 계산은 데이터에 대한 유연한 관점 (예 : 1 차원 배열로 액세스되는 다차원 배열)이 있거나 메모리 할당 자, 파일 시스템 또는 비디오 프레임 버퍼 라이브러리와 같은 스토리지를 조작하는 모든 프로그램에서 발생합니다.

자릿수 최소화

어떤 기초에서든, 가장 작은 자릿수를 사용하여 밑의 거듭 제곱 인 값의 범위를 구현하려면 0부터 시작해야합니다. 예를 들어 10 진법에서는 3 자리 숫자만으로도 0에서 999 사이의 천개의 고유 한 값을 얻을 수 있습니다. 1에서 시작하면 하나의 값만 넘치므로 4 자리 숫자가 필요합니다.

이진수의 자릿수가 하드웨어 주소 줄로 변환되므로 컴퓨터에서 중요합니다. 예를 들어 256 워드가 포함 된 ROM 칩은 0에서 255까지 주소 지정할 수 있으며 00000000에서 11111111까지 8 비트가 필요합니다. 1에서 256까지 주소가 지정된 경우 9 비트가 필요합니다. 회로 보드 나 집적 회로에 하나 이상의 주소 추적을 낭비 적으로 추가해야합니다. 실제로 실제로 일어날 수있는 일은 0이 호출 될 것입니다.해당 칩에 액세스하기위한 소프트웨어 API 레벨에서 1입니다. 워드 1에 대한 요청은 실제로 8 비트 주소 버스에 00000000을 넣습니다. 아니면, 일에 대한 요청은 예상대로 00000001를 해결하기 위해 번역,하지만 256에 대한 요청이 달리 사용되지 않는 8 비트 주소 00000000보다는 9 비트 주소 100000000이 가방 물어 뜯는 잡든지 모두를지도 할 것은 정말 의 솔루션 하드웨어, 소프트웨어 및 모든 사용자 인터페이스 및 문서에서 0에서 255까지 일관되게 사용 하면 문제를 검색 할 수 있습니다.

1 기반 변위는 기본적으로 바보입니다

예를 들어 서양 음악 이론을 고려하십시오. 우리는 7 개의 음표로 된 음계 비늘을 가지고 있지만 옥타브 를 덮는 공간이라고 부릅니다 ! 그런 다음 구간의 반전은 9 의 규칙을 따릅니다 . 예를 들어 1/3의 반전은 6 분의 1입니다 (9에서 3을 뺍니다). 따라서 세 가지 숫자 (7 개 (음표 단위), 8 개 (옥타브) 및 9 개 (거꾸로 빼기))가 매우 간단한 것입니다.

7 개의 음표가 9 중음 또는 헵 타브를 만들었고 간격이 0을 기준으로 한 경우 7에서 빼기 위해 거꾸로합니다. 7에 기초한 모든 것.

또한 간격을 쉽게 쌓을 수 있습니다. 현재 시스템에서, 우리가 5 분의 1, 4 분의 1, 3 분의 1로 다시 도약한다면, 우리는 이것들을 추가 할 수 없습니다. 결과 간격이 2 줄어 듭니다. 그것은 열두 번째가 아니라 실제로 열 번째입니다! 각 단계에서 하나를 빼야합니다. 다섯 번째로 올라간 다음 네 번째로 올라가는 것은 아홉 번째가 아니라 한 옥타브입니다.

깔끔하게 설계된 음악 시스템에서는 간격을 추가하여 결과적으로 도약 할 수 있습니다. 동일한 노트에서 시작하고 끝나는 일련의 노트는 회로 주변의 전압 법칙과 유사한 특성을 갖습니다. 모든 간격은 0에 추가됩니다.

음악 이론과 작문은 구식입니다. 촛불의 빛으로 퀼 펜으로 작곡을 한 날부터 대부분의 변화가 없었습니다.

1 기반 시스템은 제로 기반 배열을 처리 할 수없는 사람과 혼동

2000 년이 무너지자 많은 사람들이 왜 새 천년이 시작되지 않은지 혼란 스러웠습니다. 2001 년까지는 시작되지 않을 것이라고 지적한 사람들은 정당 똥꾼과 족제비로 간주되었습니다. 결국, 당신은 20 세가되면 20 대가되었습니다. 밀레니엄이 2000 년 1 월 1 일에 시작되었다고 생각했다면, 어떤 프로그래밍 언어로든 0부터 시작하는 배열에 대해 불평 할 권리가 없습니다. 그들은 당신이 얼마나 좋아하는지 정확히 작동합니다. (그렇지만, 1 기반 변위와 배열의 지지자들은 족집게와 파티 푸퍼입니다. 세기는 XX00 년에 시작해야하며, 천 년은 X000 년에 시작해야합니다.)

캘린더는 멍청하지만 적어도 하루 중 시간은 0을 기준으로합니다.

시계의 새로운 1 분마다 : 00 초로 시작합니다. 각각의 새로운 시간은 00:00 분과 초로 시작합니다. 그리고 적어도 24 시간 제로 자정이되면 낮이 돌아 다니며 11:59:59는 00:00:00으로 증가합니다.

따라서 13:53:04와 같은 시간 동안 자정부터 초를 계산하려면을 평가하면됩니다 13 * 3600 + 53 * 60 + 4. 어리석은 1덧셈이나 뺄셈이 없습니다.

MIDI에 대한 닫는 소리

좋아, 아마도 음악가들, 아마도 기술적 인 사람들은 무엇입니까?

미디! 메시지의 실제 와이어 표현에서 프로그램과 채널에 0부터 시작하는 번호 매기기를 사용하지만 gear는 1부터 시작하는 것으로 표시합니다! 예를 들어 프로그램 0에서 127까지는 대부분의 기어에서 1에서 128까지 호출되지만 일부는 0에서 127까지 호출하거나 사용자에게 선택을 제공합니다.

프로그램 71부터 80까지는 "은행"으로 간주됩니다. 예를 들어 MIDI 페달에 바로 표시됩니다. 풋 스위치는 1에서 10까지 레이블이 붙어 있으며 7 번째 뱅크에있는 경우 프로그램 71에서 80을 선택합니다. 그러나 일부 장치 또는 컴퓨터 소프트웨어는 1-128 프로그램 번호를 0에서 127로 표시하거나 사용자에게 선택! 더 나쁜 점은 1 기반 시스템 또는 1과 0을 동시에 사용하여 만든 혼란입니까?

MIDI 채널 번호는 1 ~ 16이지만 0 ~ 15 이진수로 표시됩니다. 1 기반 프레젠테이션에도 불구하고 일부 기어는 채널 번호 구성을 위해 dispswitch를 사용하며 종종 스위치는 0 기반 이진 코드를 사용합니다. 따라서 채널 3을 원하면 0010 (이진 2)으로 전환해야합니다.


1

Programming Language Concepts 클래스에서 올바르게 기억한다면 ... 0 인덱스 언어와 1 인덱스 언어는 역사적 이유와 관련이 있습니다. 프로그래밍 언어의 대기업 인 Algol-68은 Fortran과 COBOL과 같은 몇 가지 다른 "비즈니스"언어뿐만 아니라 실제로 1- 인덱싱되었습니다. 그러나 이러한 언어 중 일부에서는 실제로 시작 색인을 명시 적으로 지정할 수 있습니다. 여기에 흥미로운 테이블이 있습니다 .

기본적으로 " Ye Olde Days "수학자, 과학자 및 기타 "학술" 으로 되돌아 가면 일반적으로 0 색인 언어를 사용하는 반면 COBOL과 같은 언어 사용자는 0부터 계산을 시작하는 것이 소용이 없으므로 해당 언어에서는 더 의미가 있습니다. 1에서 시작합니다 (더 혼란스럽지 않음).

이제 귀하의 질문은 지금까지 왜 같은 이유를 참조하는 경우 컴퓨터 ( 아닌 언어 : 예 : 잘 난 정말 바이너리에 내재 된 생각입니다 ...) 당연히 시작은 0부터 세는 0000= 제로 0001등등 등등 ... = 하나 앞으로...


4
이진 표현과 관련이 없습니다. 이진수와 십진수는 모두 0부터 시작합니다 (예제에 표시된대로).
Matteo

음, 뭔가가 다른 바이너리 할 수 있습니다. 0000 ~ 1111의 4 비트로 16 워드의 메모리 뱅크를 지정할 수 있습니다. 하나를 기반으로하는 경우 0001 ~ 10000을 나타내는 5 개의 주소 라인이 필요합니다. 그렇지 않으면 예를 들어 MIDI가 채널 번호로 수행하는 작업을 수행합니다. 0000은 내부적으로 사용되지만 사용자 인터페이스는 1을 표시합니다! 하드웨어가 10 진수 기반이라면 동일한 문제 일 것입니다. 3 자리 숫자는 0부터 시작하면 천 개의 주소를 제공하지만 1부터 시작하면 4 자리가 필요합니다.
Kaz

1

숫자 0은 숫자 값, 서수, 메모리 주소 등 다양한 의미를 나타낼 수 있습니다.

'인덱스 제로'는 프로그래머가 0부터 카운트한다는 의미는 아닙니다. 할당 된 메모리 블록의 첫 번째 장소를 나타내고 '0'은 그 주소입니다.

C에서 배열을 통한 루핑은 다음과 같이 쓸 수 있습니다.

int arr[N];
for (i=0; arr[N]; ++i) {
...
}

C #에서도 동일한 작업을 수행 할 수 있습니다.

Object[] arr;

for (Object o in arr) {
...
}

두 예제 모두에 계산이 없다고 생각합니다.


1

0에서 시작하는 것은 무언가와의 거리를 설명 할 때 실용적입니다. 따라서이 배열에서 :

[4,9,25,49]

배열의 시작에서 25까지의 거리는 2입니다-두 단계를 건너 뛰어야합니다. 4까지의 거리는 0입니다. 처음부터 전혀 이동할 필요가 없습니다.

거리 (또는 인덱스)를 더할 때 이와 같이 생각하는 것이 실용적입니다. 한 단계 씩 진행 한 다음 0 단계로 이동 한 다음 2 단계로 이동합니다. 나는 인덱스 1 + 0 + 2 = 3에 있습니다. 세 단계를 건너 뛰면 위 배열에서 49로 끝납니다.


건물의 층수 계산은 실제로 같은 방식이어야합니다 (미국에서는 그렇게하지 않더라도)지면이 올라가거나 내려 가지 않았기 때문에 1 층은 0이어야합니다. 시작 위치입니다.

그러나 1 층이 가장 먼저옵니다. 1 층에있는 건물에 들어 서면 계산을 시작하고 올라 가면서 추가합니다. "건물 안에서"를 기본 / 정상 / 자연 상태로 생각한다면 제로에서 시작하는 것이 합리적입니다. 이는 도시 사회에 대한 흥미로운 논평입니다. 여러 하위 수준이 공통 인 경우지면 수준에 대한 제로도 의미가 있습니다.

1

컴퓨터에서 숫자가 어떻게 표현되는지 기억하십시오. byte변수를 보자 . 0은 이진수 로 00000000 1 로 표시됩니다 . 1은 00000001입니다. 2는 00000010입니다.

byte저장할 수있는 가장 낮은 숫자 는 0입니다. 1로 배열 인덱스를 시작하면 256 대신 길이가 255 인 배열이 있으므로 시스템이 비효율적입니다. C 프로그램의 숫자는 이진수로 컴파일되므로 ( int보통 unsigned int배열 인덱스에서 s), 0을 시작 색인으로 사용하는 것이 더 효율적이므로 자연스럽게 보입니다.

게다가, C ++에, a[p]에 전개 *(a+p*n)경우, n데이터 타입의 크기입니다. 다시 말해, a[p]"index at the element at index a+n*p"를 의미합니다. 로 p시작 하면 1index에 비어 있거나 사용하지 않은 부분이 a있습니다.

물론, "왜"라는 명백한 질문이 발생한다. 왜 00000000을 1로 설정하지 않습니까? 간단 함 : 00000000이 0 일 때 하드웨어에서 이진 추가 (전체 가산기 단위로 수행)가 쉬워집니다. 이진 추가는 모든 산술 연산의 필수 부분입니다. 1을 나타내면 컴파일러에 모든 숫자에서 1을 빼도록 지시하거나 가산기 회로를 하드 와이어로 연결하여 가산기에서 1을 먼저 빼고 다시 합산해야합니다. (캐리 비트가 관련 될 수 있으므로 나중에 뺄 수는 없습니다.)


@sec는 하드웨어 수준에서 터무니 없기 때문에 (편집 참조)
Manishearth

1

모듈로

기존의 좋은 답변이 아직 언급하지 않은 한 가지 : 0부터 시작하는 인덱싱은 모듈로 연산과 함께 작동하므로 주기적 목록을 구성하기 위해 결합 될 수 있습니다. 예를 들어

color = colors[i % colors.length]

모든 객체 가 사용될 때까지 각 객체 ((에 의해 색인화 됨 i)에 목록 colors과 다른 색상을 부여 할 수 있으며 ,이 시점에서 처음부터 다시 시작됩니다. 1 기반 인덱싱에서 동일하게 표현하는 것은 매우 어색합니다.

color = colors[(i - 1) % colors.length + 1]

랩 어라운드를 사용하여 고정 크기 부호없는 이진 산술에 의해 부과 된 자동 모듈로 연산이 이것이 합당한 이유의 또 다른 예입니다.

둘 다 수용

고려해야 할 또 다른 사항은 0 기반 배열의 첫 번째 요소를 사용 하지 않는 것이 쉽다는 사실입니다 . (이것은 foreach배열을 전체적으로 취급하는 스타일 반복 및 유사한 언어 구조를 보유하지 않습니다 .) 저를 포함하여 많은 프로그래머들은 낭비되는 공간에 대해 약간 어색하다고 느낄 수 있지만 대부분의 상황에서 이러한 걱정은 너무 적습니다. 근거가 없다. 반면에 언어가 단일 기반 색인을 사용하는 경우 많은 코드없이 색인 0에서 요소를 시뮬레이션 할 수있는 방법이 없습니다. 따라서 어떤 상황에서는 0 기반 색인이 1 기반보다 낫기 때문에 어디에서나 기준으로 0을 선택하십시오. 이는 어느 곳에서나 단일 기반이 아닌보다 유연한 접근 방식이며 구성 가능한 시작 위치보다 일관성이 있습니다.


0

컴퓨터 시스템은 자연수 (0부터 계산)와 정수 (1부터 계산)를 모두 사용합니다. 사람들은 정수로 물건을 세어 번호 매기기 목록에 직관적으로 만들며 많은 프로그래밍 언어가이를 활용합니다. 기본, 코볼, 포트란, 루아 및 파스칼은 모두 1부터 계산합니다. 이러한 언어는 데이터 처리, 수치 분석, 간단하고 직관적 인 목록이 유리한 경우 교육.

순서대로 모든 것을 처리하는 대신 데이터 구조를 분석하고 조작하기 시작하면 정수가 어색해집니다. 수식이나 알고리즘에서 시퀀스를 참조해야하는 경우 수학자가하는 것처럼 a 0 , a 1 , n 등 의 순서로 0 부터 시작하는 것이 더 쉽고 오류가 덜 발생 합니다. 그렇지 않으면 +1로 조정해야합니다. –1-올바른 데이터를 얻으려면 오류가 발생하기 쉽고 버그가 발생하기 쉽습니다. 따라서 컴퓨터 과학자를 위해 설계된 언어는 일반적으로 자연수를 사용합니다. C, Java 및 Lisp는 모두 0부터 계산됩니다.

프로그래밍 언어 외에도 많은 컴퓨터 시스템이 0부터 시작합니다. 왜냐하면 컴퓨터 과학자들이 사용했던 것이기 때문입니다. 또한 1부터 번호 매기기가 너무 교활한 버그로 이어지기 때문에 많은 사람들이 기술이 아닌 최종 사용자를 위해 엄격하게 설계된 인터페이스 요소 외부에서는 피해야합니다.


컴퓨터 과학자들을위한 Java ... 롤!
Kaz

0

간단한 대답은 첫 번째 숫자가 1이 아니라 0이라는 것입니다.

설명 : 임의의 기준에서 여러 자리 수를 계산하는 공식은 다음과 같습니다.

n = sum(i=0 to n, Di^i)

WHERE 
n = numeric result
i = index (starting with 0)
Di = is the digit at index i

십진수 시스템을 보자. 우리가 가장 익숙한 시스템이다.

숫자 1234를 보면 다음과 같이 쓸 수 있습니다.

4 x 10^0 = 4
3 x 10^1 = 30
2 x 10^2 = 200
1 x 10^3 = 1000

in other words, sum of digits raised to the power if their index.

따라서 그것은 컴퓨터뿐만 아니라 우리도 사람들이 0부터 계산합니다.


0

배열 인덱스는 기본 메모리 위치에서 요소의 메모리 위치까지의 오프셋입니다. 요소 i는베이스 + i입니다. 첫 번째 요소는 기본 위치에 있으므로 위치 0 (기본 + 0)에 있습니다.


0

계산 효율성 외에도 계산에 또 다른 측면이 있습니다. 시퀀스의 각 요소에 순차적 번호를 부여하는 두 가지 방법이 있습니다.

  1. 선행 (전체) 요소 수 (기수)
  2. 요소의 위치 (정수)

사람들의 나이는 기본 숫자입니다. 아기가 태어난 후 첫해에는 0 세입니다. 왜냐하면 0 년 동안 살아 있었기 때문입니다.

연도는 서수입니다. 첫해 Anno Domini (AD)에서 연도는 AD 1입니다. 어떤이없는 것처럼, 더 년 0 없습니다 영차 아무것도.

: 엘리먼트의 인덱스 배열에서의 위치 (1)로부터 계산 시작 나타낸다 (예컨대 MATLAB 및 티카 등) 프로그래밍 언어 소자. 다른 모든 언어 (예 : 모든 C 기반 언어)에서 요소의 색인은 선행 요소의 수이므로 첫 번째 요소는 0입니다.


물론 Matteo는 0부터 시작하는 색인화가 더 효율적이라고 언급 할 때 부분적으로 만 정확 합니다.

element(n) = address + n * element_size

모든 어레이 주소에 이미 하나를 element_size빼면 1 기반 색인 생성이 효율적일 수 있습니다 . 이것은 배열이 할당 될 때 수행 될 수 있으며,이 경우에도 매우 빠릅니다.

array_address = address - element_size
element(n) = array_address + n * element_size

-1

컴퓨터는 전통적으로 0부터 시작하여 숫자 값을 집계합니다. 예를 들어 C 기반 프로그래밍 언어의 배열은 인덱스 0에서 시작합니다.

0… 프로그래밍 언어, 컴퓨터 및 계산과 같은 다른 개념을 망쳐 놓고 있습니다.

  1. 2 개의 상태 (대부분은 개략적으로 정확하게 수행)를 사용하면 2 자리를 선택하여 매핑 할 수 있습니다 (예 : 참조). "3"과 "5"(또는 "F"와 ",")는 문제가 없지만 컴퓨터가 왜 "3"(또는 "F")에서 계산되는지 묻습니다. 당연히 선택은 0과 1입니다.
  2. 파스칼의 배열은 1부터 시작합니다.이 언어는 저수준 C보다 다소 추상적입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.