Arrays
Os arrays no Kriol são colecções de tamanho fixo de elementos do mesmo tipo.
Serve para quando tens muitos valores da mesma espécie: em vez de nota1, nota2, nota3, tens um nota com um índice.
Declaração com inicialização
Seção intitulada “Declaração com inicialização”<tipo>[<tamanho>] <nome> = [<valor1>, <valor2>, ...];int[3] nums = [10, 20, 30];bool[2] flags = [sin, nau];O número entre [ ] faz parte do tipo, não do nome: int[3] lê-se “array de 3 inteiros”. Tem de ser um literal, e o número de valores entre [ ] tem de corresponder exactamente.
O literal [ ... ] sem tipo explícito é interpretado pelo contexto da variável
ou campo que o recebe. Quando o contexto não deixa claro o tipo do array, usa
um literal tipado, escrevendo o tipo dos elementos seguido de [] entre parênteses:
int[3] valores = (int[]) [1, 2, 3];Inicialização por repetição
Seção intitulada “Inicialização por repetição”Para preencher um array com o mesmo valor em todas as posições, usa a sintaxe [valor; N], em que N é o número de elementos:
int[5] zeros = [0; 5];num[10] uns = [1.0; 10];O N tem de ser igual ao tamanho declarado do array. É a forma habitual de criar um array que vais preencher depois num ciclo, já que no Kriol nenhuma variável fica sem valor inicial.
Acesso a elementos
Seção intitulada “Acesso a elementos”Os índices começam em 0:
int[5] seq = [1, 2, 3, 4, 5];mostran(seq[0]); // 1mostran(seq[4]); // 5seq[2] = 99;mostran(seq[2]); // 99Num array de N elementos, o último índice válido é N - 1, e é por isso que um ciclo sobre um array se escreve i < N e não i <= N.
O índice pode ser qualquer expressão de tipo inteiro, com ou sem sinal, mas não pode ser um real:
int[3] v = [1, 2, 3];int i = 1;u8 j = 2;
mostran(v[i + 1]); // 3mostran(v[j]); // 3// mostran(v[1.0]); // ERRO: o índice de um array tem de ser um número inteiroÍndices fora dos limites
Seção intitulada “Índices fora dos limites”Um índice fora do array termina o programa com uma mensagem que indica a linha, o índice e os limites:
programa.kriol:5: erro de execução: o índice 3 está fora do array, que vai de 0 a 2Essa verificação acontece em execução, a cada acesso, mesmo quando o índice é um literal: v[7] num int[3] compila sem queixas e falha ao correr. Em troca, nunca lês nem escreves memória que não é tua, ao contrário do que acontece em C.
Uso com ciclos
Seção intitulada “Uso com ciclos”int[10] seq = [0; 10];
pa int i = 0; i < 10; i += 1 { seq[i] = i * i;}
mostran(f"Quadrados: {seq}");O tamanho não se pode perguntar ao array: não há seq.tamanho nem konta(seq). Como é fixo e conhecido na compilação, o costume é guardá-lo numa variável de topo, como int tamanho = 10;, e usá-la no ciclo. Note-se que o nome não pode ser TAMANHO: começar por maiúscula está reservado para moldes, por isso não há a convenção de constantes em maiúsculas de outras linguagens.
Arrays multidimensionais
Seção intitulada “Arrays multidimensionais”Um array pode ter várias dimensões. Como em C e em Go, o primeiro tamanho é a dimensão de fora: int[2][3] tem 2 linhas de 3 elementos.
int[2][3] m = [[1, 2, 3], [4, 5, 6]];int[3][2] zeros = [[0; 2]; 3]; // 3 linhas de [0, 0]
mostran(m[1][2]); // 6zeros[2][1] = 9;
pa int i = 0; i < 2; i += 1 { pa int j = 0; j < 3; j += 1 { mostra(m[i][j]); }}Cada linha é ela própria um array (m[1] é um int[3]), que se pode copiar, imprimir ou passar a uma função:
m[0] = m[1]; // copia a linha 1 para a linha 0int[3] linha = m[1]; // uma cópia da linhamostran(m); // [[4, 5, 6], [4, 5, 6]]Arrays como valores
Seção intitulada “Arrays como valores”Como os moldes, os arrays são valores: atribuir, passar a uma função ou devolver um array copia-o por inteiro.
fn dobra(int[3] v) int[3] { pa int i = 0; i < 3; i += 1 { v[i] *= 2; // altera a cópia local } divolvi v;}
fn inisiu() { int[3] a = [1, 2, 3]; int[3] b = dobra(a); // a continua [1, 2, 3] a = dobra(a); // atribuição do array inteiro a = [a[2], a[1], a[0]]; // o novo valor é construído antes de ser guardado mostran(dobra([5; 3])[2]); // 10}Isto distingue o Kriol do C, onde um array passado a uma função é um ponteiro e a função altera o original. Aqui é mais fácil de prever, mas copiar um array grande a cada chamada leva tempo e ocupa pilha.
O tamanho faz parte do tipo, e os tipos têm de ser iguais: um int[3] só aceita outro int[3], e não um int[4] nem um u8[3]. Um literal [ ... ] ou [valor; N] também pode ser usado diretamente como argumento, valor de divolvi, valor de uma atribuição ou valor depois de sinon, e recebe o tipo do destino.
Para alterar um array de quem chama, devolve o novo valor e atribui-o, como em a = dobra(a);.
Impressão de arrays
Seção intitulada “Impressão de arrays”Podes passar um array diretamente a mostra / mostran ou usá-lo numa f-string para imprimir todos os elementos:
int[3] a = [1, 2, 3];mostran(a); // [1, 2, 3]mostran(f"Array: {a}"); // Array: [1, 2, 3]Os elementos aparecem entre [ ], separados por vírgula e espaço, e cada um é escrito como se fosse impresso sozinho: um num[2] sai [1.5, 2], um bool[2] sai [sin, nau] e um int[2][2] sai [[1, 2], [3, 4]].
Arrays também podem aparecer como campos de um molde:
molda Pessoa { textu nomi; int[2] flags;}
fn inisiu() { Pessoa pessoa = Pessoa{nomi = "jose", flags = [0, 1]}; mostran(f"Flags: {pessoa.flags}"); // Flags: [0, 1]}Arrays de valores de moldes podem ser guardados e indexados. Isto permite encadear acesso a índice e campo:
molda Enderesu { textu rua; int numero;}
molda Pessoa { Enderesu[2] enderesus;}
fn inisiu() { Pessoa pessoa = Pessoa{ enderesus = [ Enderesu{rua = "antigu", numero = 10}, Enderesu{rua = "nobu", numero = 44} ] };
pessoa.enderesus[0].rua = "medio"; pessoa.enderesus[0].numero += 5;
mostran(pessoa.enderesus[0].rua); // medio mostran(pessoa.enderesus[0].numero); // 15}Restrições actuais
Seção intitulada “Restrições actuais”- O tamanho do array deve ser um literal inteiro. Não pode ser uma variável.
- Não há arrays de tamanho variável, nem forma de crescer ou encurtar um array.
- O array não guarda o seu tamanho: não há
tamanhonemkonta(). - Um array declarado dentro de uma função fica na pilha e pode ocupar no máximo
1 MiB (por exemplo, 131 072 valores
int). Arrays maiores devem ser declarados fora das funções; vê Tamanho das variáveis locais. - Aceder a um índice fora do array termina o programa com uma mensagem de erro que indica a linha e o índice.
- Literais sem tipo explícito precisam de um contexto de array. Se o compilador
não conseguir inferir o alvo, usa
(tipo[]) [...]. - Arrays de valores de moldes podem ser usados, mas não podem ser impressos como
um todo com
mostra,mostranou f-strings; imprime campos individuais ou arrays de tipos primitivos. - Um array passado a uma função ou devolvido por ela é copiado, por isso o limite de 1 MiB aplica-se também aos parâmetros e aos tipos de retorno.
- Cada dimensão pode ter no máximo 1 048 576 elementos.