Vetores começando em 0 ou em 1? Intervalos abertos ou fechados?

Antes eu falei de passagem de parâmetros. Eu achava que se seguisse nesse nível, eu acabaria comentando sobre o uso de ponto-e-vírgula em linguagens de programação. Mas surgiu um tópico um pouquinho (só um pouco) menos “mundano” do que o ponto-e-vírgula, hehe… A indexação de vetores.

Existem tantas linguagens onde os vetores (arrays, listas, o que for) começam com o índice 0 que eu até estranhei quando tive que mexer no Matlab, onde os índices das matrizes sempre começam em 1. O Matlab sempre salva a minha vida (sempre tem aquela função matemática pronta que levaria dias pra implementar em outra linguagem), mas não quer dizer que eu não estranhe certas características dele…

Em, C, C++, Java e Python já tinha me acostumado que o tamanho do vetor e o seu último elemento eram coisas diferentes. Que o segundo elemento é o de índice 1, e o primeiro é o de índice 0. Que, num vetor de tamanho ímpar dividindo o tamanho por 2 (e truncando a parte fracionária, como é o default em C, C++ e Java), eu obtenho o elemento que está exatamente no meio. Que, se eu quiser andar em círculos nos primeiros 5 elementos, eu posso incrementar o contador assim: i = (i + 1) % 5 (onde o operador % também é conhecido por mod, isto é, o resto da divisão). Que, se eu quisesse andar no vetor de 10 em 10 elementos, era só fazer 0*10, 1*10, 2*10, 3*10, etc., tudo bem ajeitadinho. O primeiro bloco vai de 0 a 9, o segundo de 10 a 19, e assim por diante. Se a linguagem oferecer outros recursos no acesso às listas, como o Python, melhor ainda: lista[0:10] inclui os primeiros 10 elementos, de 0 a 9; lista[10:20] inclui os elementos de 10 a 19; e lista[20:30] representa os elementos de 20 a 29. Reparem que não foi necessário fazer nenhum “+1” nem “-1” pra compensar elementos finais nem iniciais, pois os intervalos são abertos no final. E reparem que calculando 30-20, por exemplo, descobrimos que a sublista tem 10 elementos.

Agora no Matlab, como fica? Os vetores começam em 1. Se eu quero andar em círculos nos primeiros 5 elementos, a fórmula fica: i = mod(i, 5) + 1 (agora, em vez do %, usei mod, já que estou no Matlab). Percebam que o “+1”, neste caso, fica fora do da operação mod… Os subintervalos incluem tanto o índice menor quanto o índice maior. Portanto, lista(20:30) (a sintaxe usa parênteses, mas isso é um detalhe), é uma sublista de 11 itens (fim – inicio + 1). Se eu estou calculando usando intervalos de 10 em 10, o primeiro elemento do primeiro bloco é 0*10+1, o do segundo bloco é 1*10+1, e assim por diante. O exemplo que eu escrevi em Python acima, fica assim no Matlab: lista(1:10), lista(11,20), lista(21,30). Isso me lembra a nossa numeração de séculos onde o ano 2000 é o último ano do século 20, e não o primeiro do século seguinte! Pois então, ficou tudo cheio de +1 aqui, -1 ali. Mas pelo menos ninguém precisa aprender que o segundo elemento se indexa com [1].

Pra complicar mais um pouco, a linguagem de script do editor Vim, os índices começam em 0, mas os intervalos são inclusivos. Bela mistura: lista[0:9], lista[10:19], lista[20:29]. Parece interessante (apesar de ter que calcular manualmente um “-1” pra indicar o final do intervalo), mas não mexi muito com o VimScript (nem pretendo, a linguagem é muito esquisita, embora seja bem prática, às vezes), então não sei qual das três possibilidades eu gosto mais…

Qual é o melhor? Sei lá. O fato é que a gente se confunde, se confunde, mas se acostuma. Depois de um tempo, fica tudo “redondo” e parece óbvio. Até o momento de usar outra linguagem. Aí a gente mistura tudo e fica perdido. Deve servir pra desenferrujar o cérebro que já estava acostumado demais com esses truquezinhos, hehe. O que eu escolheria se eu fosse criar uma linguagem? Eu achei interessante o estilo Python, mas do mesmo jeito que muitas linguagens copiaram o C sem ao menos corrigir deficiências óbvias (ex.: necessidade de break no switch), é necessário pensar um pouco antes de copiar aquilo que todo mundo faz. Aliás, não é só a linguagens de programação que essa regra se aplica…

Anúncios

4 pensamentos sobre “Vetores começando em 0 ou em 1? Intervalos abertos ou fechados?

  1. Nenhuma das alternativas acima. Meu voto vai para o bash, que conta arrays do 0, e usa start:length ao invés de start:end para pegar uma porção do array: ${lista:0:10}, ${lista:10:10}, ${lista:20:10}, etc. (Sim, a sintaxe do bash é tenebrosa, mas o ponto é usar start:length ao invés de start:end…) Se bem que para algumas coisas start:end faz mais sentido (e.g., pesquisa binária). Hmmrgh…

    [Sim, eu vi que o post é de cinco anos atrás. :P]

  2. Ô, bash é “lindíssimo” com seus $(()), [[ ]], agora com ${lista[@]:0:10} ficou melhor ainda :-p

    CINCO anos desde este post! Estou ficando velho! Desde então nunca mais usei o Matlab, passei a programar em Java e PL/SQL (argh para ambas) e aprendi a odiar a Oracle mais que a Microsoft e a Apple juntas.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s