Esta é uma pergunta sobre a qual me pergunto (e me perguntam) há muito tempo.
Em (quase? Todas?) Linguagens de programação, um índice começa em zero para uma matriz, string etc. Eu reconheço que se tornou uma convenção ao longo do tempo, adotada em muitas linguagens, mas alguém pode apontar a origem disso?
Eu pensei que talvez tivesse a ver com tudo estar enraizado no binário. Mas não tenho certeza da idéia que leva à necessidade no sistema decimal - por que não iniciar um índice a partir de 1?
Alguém tem conhecimento histórico de linguagens de programação em que a decisão de iniciar índices em zero possa ter sido explicada?
Obrigado!
EDIT: Os escritos de Dijkstra são mais úteis do ponto de vista matemático, mas mesmo ele observou, nem todas as línguas são indexadas a zero. A explicação do WBT também faz sentido sobre por que alguém começaria com zero com base nos endereços de memória. (Eu sei que algumas linguagens manipulam a indexação um pouco diferente com base na manipulação da matriz.)
Eu não estou necessariamente procurando o porquê (que eu aprecio muito porque ajuda a entender mais), mas mais ao longo de quando isso se tornou a convenção e / ou se pode ser rastreado para um idioma específico.
Assim, por exemplo, no C de K&R, ao discutir índices de matriz, K ou R explica com simplicidade: "Os subscritos de matriz sempre começam em zero em C ..." (p. 22) Posteriormente, ao discutir uma função para processar caracteres matrizes, "... um design mais útil seria retornar o comprimento da linha ou zero se o final do arquivo for encontrado. Zero é um retorno aceitável no final do arquivo, porque nunca é um comprimento de linha válido." (p. 127)
Com base em K&R, concluo: a) a convenção é adotada de outro lugar; portanto, C não é a inspiração por trás da indexação zero eb) existem possíveis razões mais profundas para seu uso com base no segundo exemplo. Eu sei que o K&R é tão amplamente considerado por sua prosa clara, então esse é outro motivo para incluí-lo, para dar um exemplo do que eu esperava que outra linguagem documentada fizesse para explicar o motivo por trás da indexação zero.
Eu acho que o WBT e o btilly oferecem igualmente boas razões; Eu me perguntei se alguém que talvez conhecesse idiomas antigos (pré-C?) Que documentassem a decisão de design. E, ao mesmo tempo, reconheço que essas informações podem não existir.
fonte
Respostas:
É sobre compensações. Você tem um endereço, que aponta para o local na memória onde a matriz começa. Em seguida, para acessar qualquer elemento, você multiplica o índice da matriz pelo tamanho do elemento e o adiciona ao endereço inicial, para encontrar o endereço desse elemento.
O primeiro elemento está no ponto de partida, então você multiplica o tamanho do elemento por zero para obter zero, que é o que você adiciona ao endereço inicial para encontrar a localização do primeiro elemento.
A convenção se espalhou porque os programadores começaram a trabalhar em linguagens de nível muito baixo, onde os endereços de memória eram manipulados diretamente e, na maioria dos casos, construídos a partir daí, mantendo a mesma convenção a cada etapa, para que não precisassem reaprender ou estar propenso a erros quando alternando entre convenções. Ainda é importante entender como esse endereçamento funciona, especialmente quando se trabalha com idiomas de nível inferior. Concordo que isso pode ser um obstáculo para as pessoas que estão aprendendo a programar em um idioma de nível superior.
O artigo da Wikipedia sobre esse tópico também cita uma instrução de máquina comum usada ao trabalhar "para trás" e detectar o final de um loop, a saber "diminuir e pular se zero".
Uma exceção: o MATLAB e algumas outras linguagens resistiram à tendência e seguiram com um índice começando em 1, aparentemente com a impressão de que seria a primeira linguagem de programação para muitos usuários-alvo e que, para essas pessoas, começar com 1 faz mais senso intuitivo. Isso causa algumas frustrações para os (relativamente pequenos subconjuntos de?) Programadores que frequentemente alternam entre linguagens de programação que começam a contar com valores diferentes.
fonte
A declaração "(na maioria das linguagens de programação), um índice começa em zero" simplesmente não está correta. As línguas cuja herança deriva formal ou informalmente de C seguem esta convenção. Outros podem não.
C fez dessa maneira porque C era fundamentalmente destinado a ser um montador de "alto nível". Isso sobrecarregava bastante a carga de trabalho do programador, onde outros idiomas tinham o compilador e a máquina fazendo o trabalho pesado. No momento em que C foi desenvolvido, a contagem baseada em 1 era a norma, mas exigir que o compilador acompanhasse esse bobo extra 1 era considerado muito trabalho para o compilador.
O C ++ obteve do C devido ao requisito de que o C ++ seja compatível com versões anteriores (alguns podem dizer que é compatível com erros) com C. Java o obteve do C. Idiomas desenvolvidos por programadores de C sem exposição significativa a qualquer outra coisa que fosse copiada do C, porque eles queria ser popular com outros programadores C ou eles não conheciam outra maneira de fazê-lo.
O FORTRAN, que antecede quase tudo o resto, começou em 1, porque engenheiros, matemáticos e cientistas têm contado a partir de 1 por milênios. (Isso permite um algoritmo muito conciso e muito bom para o problema das 8 rainhas.) O MATLAB copiou o FORTRAN, pois era destinado quase precisamente à mesma comunidade de usuários.
O PASCAL na verdade exige que o programador diga onde ele inicia e termina, permitindo definir, por exemplo, e matriz cujos índices variam de, por exemplo, -7 a +7. Ada seguiu PASCAL. (Mencionar Ada deve ser bom por pelo menos três votos negativos).
Acredito que o COBOL começou em 1, mas não me lembro ao certo e não tenho a intenção de refrescar algumas lembranças muito dolorosas, porque contadores, como engenheiros, cientistas e matemáticos, começam a contar em 1.
É minha lembrança distante que PL / I permiti que você começasse e parasse onde quisesse. Divulgação completa: Eu nunca fiz a codificação PL / I, apenas procurei em um livro e não tenho intenção de mudar isso.
Eu nunca usei matrizes no GPSS (pacote de simulação de eventos discretos da IBM) durante minha breve exposição a ele, por isso não posso dizer como o GPSS fez isso.
As linguagens assembly geralmente iniciam de 0 porque as matrizes são tradicionalmente definidas em termos de um endereço inicial e um deslocamento do endereço inicial. (Esse nem sempre é o caso. O IBM 1130 Executive tinha uma grande tabela de vetores residentes, cujo "endereço inicial" estava realmente no meio da tabela. Eles fizeram isso porque o endereçamento indexado 1130 permitia compensações assinadas, exigindo que as compensações iniciassem em zero teria jogado fora metade do tamanho possível da tabela, e essa tabela PRECISA ser grande.)
fonte
Tentando uma resposta curta.
Contar a partir de zero é popular não apenas em linguagens de programação, mas em matemática de maneira mais geral.
A contagem é muito mais antiga que o zero. Desde que a notação zero e a posição foram inventadas, todo mundo conta 10s, 100s, 1000s etc. do zero: é o novo dígito mais baixo. A contagem de unidades a partir do zero também traz algumas vantagens de consistência, principalmente com intervalos semiabertos e matrizes (multidimensionais). Para mais detalhes e exemplos, consulte os links à direita e https://en.wikipedia.org/wiki/Zero-based_numbering
fonte
Todas as convenções possíveis de contagem foram tentadas. A contagem da convenção zero se tornou dominante porque as alternativas tendem a ser mais propensas a acidentes.
Consulte https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html para obter uma explicação sobre por que esta versão funciona melhor.
fonte