Listas de valores: arrays
Quando você precisa guardar várias coisas do mesmo tipo, não declare uma variável para cada.
Imagine que você quer armazenar o placar dos 10 melhores jogadores. Você poderia criar 10 variáveis: placar1, placar2, ..., placar10. Mas isso é ruim por dois motivos: dá trabalho e fica impossível percorrer todos com um laço de repetição. A solução é o array — uma variável que guarda muitos valores, acessados por um índice numérico.
Declarando um array
A sintaxe é parecida com a do DIM normal, mas com o tamanho entre parênteses logo após o nome:
DIM nomeArray(tamanho) AS TIPO
DIGITE E VEJA
Programa 5.1 — Cinco notas
Vamos guardar 5 notas e exibir cada uma:
USES SCREEN 1
SCREEN 1
CLS
DIM notas(4) AS BYTE ' cria notas(0), notas(1), ..., notas(4)
notas(0) = 80
notas(1) = 95
notas(2) = 70
notas(3) = 88
notas(4) = 100
PRINT "NOTA 0 = ", notas(0)
PRINT "NOTA 4 = ", notas(4)
ATENÇÃO
DIM (4) cria CINCO posições, não quatro!
Em CSX (como no BASIC clássico), o tamanho do array é o último índice, não a quantidade de elementos. DIM notas(4) cria as posições 0, 1, 2, 3 e 4 — cinco no total. Esse detalhe pega muita gente desprevenida; preste atenção.
CURIOSIDADE
Por que indexar a partir de zero?
Por uma razão técnica do compilador: o endereço do elemento i é calculado como endereçoBase + i * tamanhoDoTipo. Se começássemos do 1, o compilador teria que subtrair 1 antes de cada acesso. Em todas as linguagens herdeiras de C, índices começam em zero.
Percorrendo um array com FOR
Arrays brilham quando combinados com laços. O programa abaixo preenche uma tabela de quadrados de 0 a 5:
DIGITE E VEJA
Programa 5.2 — Tabela de quadrados
Note como uma única linha do FOR substitui seis comandos separados:
USES SCREEN 1
SCREEN 1
CLS
DIM quad(5) AS WORD
DIM i AS BYTE
FOR i = 0 TO 5
quad(i) = i * i
NEXT i
PRINT "TABELA DE QUADRADOS:"
FOR i = 0 TO 5
PRINT " ", i, " AO QUADRADO = ", quad(i)
NEXT i
TELA ESPERADA
Saída esperada
TABELA DE QUADRADOS:
0 AO QUADRADO = 0
1 AO QUADRADO = 1
2 AO QUADRADO = 4
3 AO QUADRADO = 9
4 AO QUADRADO = 16
5 AO QUADRADO = 25
Onde os arrays moram na memória
Quando o compilador encontra um DIM array, ele reserva um espaço contíguo na RAM do MSX1. O endereço base começa em $C200 e cresce conforme você declara mais arrays e variáveis. BYTE ocupa 1 endereço por elemento, WORD e INT ocupam 2. Você pode ver isso na aba Assembly (Z80).
ATENÇÃO
Não há verificação de limites!
Se você declarou DIM a(5) e acessar a(10), o programa vai compilar e rodar — mas vai escrever em uma região de memória que não pertence ao seu array, corrompendo outras variáveis ou o próprio MSX1. Em jogos, isso causa bugs misteriosos. Sempre confira que seus índices estão dentro do tamanho.
DICA
Constantes ajudam
Use uma constante para o tamanho, e refira-se a ela tanto no DIM quanto no FOR. Se um dia mudar o tamanho, muda em um lugar só.
CONST N_NOTAS = 9
DIM notas(N_NOTAS) AS BYTE
FOR i = 0 TO N_NOTAS
notas(i) = 0
NEXT i
Usos típicos em jogos
Arrays são onipresentes em jogos:
- Posições de inimigos:
DIM ene_x(7), ene_y(7) AS BYTE— 8 inimigos. - Mapa de fase:
DIM mapa(255) AS BYTE— 256 quadrículas. - Tabelas pré-calculadas: seno, cosseno, etc.
- Highscores:
DIM hi(9) AS WORD— top 10.
Exercícios
- 5.1 — Crie um array
cores(15) AS BYTEe atribua a cada posição o próprio índice usando FOR. - 5.2 — Faça um programa que calcula a soma dos elementos do array anterior e mostra o total.
- 5.3 — Por que o exercício 5.2 precisaria de uma variável WORD para a soma, e não BYTE?
Resumo do capítulo
- Array = uma variável que guarda muitos valores do mesmo tipo.
- DIM nome(N) AS TIPO cria N+1 elementos: nome(0) até nome(N).
- Acesso por índice:
nome(i)para ler ou escrever. - Combinam perfeitamente com laços FOR.
- Não há proteção contra estouro de índice — você é o responsável.
Guardando tabelas com DATA, READ e RESTORE
Para encher um array ou desenhar um bloco, não é preciso escrever um VPOKE por linha. Como no MSX BASIC, guarde os números em linhas DATA e leia com READ:
DIM v AS BYTE
DIM i AS BYTE
' Desenho de uma estrela (8 linhas)
FOR i = 0 TO 7 : READ v : VPOKE $170 + i, v : NEXT i
Inimigos:
DATA 10, 20, 30, 40
DATA $3C, $42, $5A, $FF, $FF, $5A, $24, $00
DATA n, n, ...guarda números constantes (decimais, negativos ou$hex). Os DATA podem ficar em qualquer lugar do programa, e são lidos na ordem em que aparecem.READ a, b(i), ...pega o próximo número e guarda numa variável ou num elemento de array.RESTOREvolta a leitura para o primeiro DATA.RESTORE rotulovolta para o DATA logo depois daquele rótulo.
Os números ficam no cartucho, e não na RAM, então uma tabela grande quase não gasta memória. Usar READ sem nenhum DATA no programa dá erro na compilação.