Arrays em C#
Nesta aula você aprenderá o que é um array (vetor), por que ele existe e como declará-lo e utilizá-lo em C#. Leia cada bloco antes de ir para a lista de exercícios.
O que é um vetor e por que existe
Declaração, indexação e a propriedade Length
O problema sem vetor
Imagine que você precisa armazenar as notas de 5 alunos para calcular a média da turma. Sem arrays, a solução mais direta seria declarar uma variável separada para cada nota:
double nota1 = 7.5;
double nota2 = 8.0;
double nota3 = 6.5;
double nota4 = 9.0;
double nota5 = 5.0;
// Sem for: cada variável tem um nome diferente
double media = (nota1 + nota2 + nota3 + nota4 + nota5) / 5;
Console.WriteLine("Média: " + media);
Para 5 alunos ainda dá para tolerar. Mas e se a turma tiver 30 alunos?
Você teria 30 declarações e uma linha de média gigante. Pior: não seria
possível usar um for para percorrer as notas
sistematicamente — cada variável tem um nome diferente e não há como
acessá-las pelo número da posição.
Com vetor: uma variável, vários valores
Um array é uma única variável que guarda uma coleção de
valores do mesmo tipo, cada um acessível por um número de posição chamado
índice. Com ele, o for pode percorrer todos
os elementos de forma uniforme:
double nota1 = 7.5;
double nota2 = 8.0;
double nota3 = 6.5;
double nota4 = 9.0;
double nota5 = 5.0;
// Não há como usar for aqui
double soma = nota1 + nota2
+ nota3 + nota4
+ nota5;
double[] notas = { 7.5, 8.0, 6.5,
9.0, 5.0 };
double soma = 0;
for (int i = 0; i < notas.Length; i++)
{
soma += notas[i];
}
O array notas guarda os 5 valores em posições numeradas,
começando sempre em zero:
Anatomia da declaração
Existem duas formas de criar um array em C#:
double[] notas = new double[5];
// Todos os elementos começam em 0.0 automaticamente
notas[0] = 7.5;
notas[1] = 8.0;
// ...
double[] notas = { 7.5, 8.0, 6.5, 9.0, 5.0 };
// O tamanho é definido automaticamente pelo número de valores
-
double[]
O tipo do array. Os colchetes
[]distinguem um array de uma variável simples do tipodouble. - notas O nome da variável — segue as mesmas regras de qualquer nome de variável em C#.
-
new double[5]
Aloca espaço na memória para 5 valores do tipo
double. Todos são inicializados em0.0. -
notas[i]
Acessa o elemento na posição
i. O índice começa em0e vai aténotas.Length - 1. -
notas.Length
Propriedade que retorna o número de elementos. Para
notas, vale5. Use-a sempre no lugar de números literais.
Um array de tamanho N tem índices de 0 até
N - 1. Tentar acessar v[N] causa
erro em tempo de execução. Use sempre
v[v.Length - 1] para o último elemento —
nunca um número literal.
O índice i do for serve diretamente como índice
do array: notas[i] muda de elemento a cada iteração,
percorrendo toda a coleção. A condição i < notas.Length
garante que o laço para exatamente quando o array acaba — sem número
fixo no código.
Sintaxe: três formas de declarar
Length e o erro IndexOutOfRangeException
Três formas de declarar um array em C#
C# oferece três sintaxes para criar um array. Todas produzem o mesmo resultado — a diferença está em quando você conhece os valores e o tamanho.
int[] v = new int[4]; // cria 4 posições, todas com 0
v[0] = 10;
v[1] = 20;
v[2] = 30;
v[3] = 40;
Ideal quando o tamanho é conhecido mas os valores serão lidos do usuário
ou calculados em seguida. Os elementos começam com o valor padrão do
tipo: 0 para int/double,
false para bool, null para
string.
int[] v = new int[] { 10, 20, 30, 40 };
// ou, de forma mais curta:
int[] v = { 10, 20, 30, 40 }; // o compilador infere o tamanho
Ideal para valores fixos já conhecidos em tempo de escrita do programa — tabelas, constantes, dados de teste.
Console.Write("Quantos alunos? ");
int n = Convert.ToInt32(Console.ReadLine());
double[] notas = new double[n]; // tamanho definido em tempo de execução
for (int i = 0; i < notas.Length; i++)
{
Console.Write($"Nota do aluno {i + 1}: ");
notas[i] = Convert.ToDouble(Console.ReadLine());
}
Quando o programa não sabe antecipadamente quantos elementos haverá,
lê-se o tamanho do usuário e passa-o para new double[n].
O resultado é um array do tamanho exato pedido — sem desperdiçar
memória e sem limitar o programa a um número fixo.
A propriedade Length
Todo array em C# possui a propriedade .Length, que retorna
o número de elementos. Ela é fundamental: use-a sempre no lugar de
números literais no for.
int[] v = { 10, 20, 30 };
for (int i = 0; i < 3; i++) // 3 gravado no código
{
Console.WriteLine(v[i]);
}
// Se v ganhar um 4º elemento,
// precisa lembrar de mudar o 3.
int[] v = { 10, 20, 30 };
for (int i = 0; i < v.Length; i++)
{
Console.WriteLine(v[i]);
}
// Funciona automaticamente
// para qualquer tamanho de v.
-
v.Length
Retorna um
intcom o número de elementos. Para{ 10, 20, 30 }, vale3. -
i < v.Length
O laço termina quando
ichega av.Length— exatamente um passo depois do último índice válido. -
v[v.Length - 1]
Acessa o último elemento. Evite
v[2]ou qualquer literal; use sempreLength - 1.
Erro comum: IndexOutOfRangeException
Se você tentar acessar uma posição que não existe — índice negativo ou maior ou igual ao tamanho do array — o C# lança uma IndexOutOfRangeException e o programa para.
int[] v = { 10, 20, 30 }; // índices válidos: 0, 1, 2
for (int i = 0; i <= v.Length; i++) // BUG: <= inclui i=3
{
Console.WriteLine(v[i]); // v[3] não existe → exceção!
}
Experimente abaixo: informe um índice e veja se ele é válido para um
array de tamanho 5 (índices 0 a 4).
Use sempre i < v.Length (estritamente menor) na
condição do for. O último índice válido é
v.Length - 1. Qualquer acesso com
i = v.Length já está fora dos limites.
For + vetor: os padrões fundamentais
Imprimir, reverso, soma, mínimo/máximo, leitura do console
Quase todo algoritmo com arrays combina um for com um dos
padrões a seguir. A variável i não é apenas o contador do
laço — ela é o índice que seleciona qual célula do array
está sendo processada naquela iteração.
Padrão 1 — Imprimir todos os elementos
| i | — |
| v[i] | — |
Padrão 2 — Percorrer em ordem reversa
Para percorrer de trás para frente, o for começa em
v.Length - 1 e decrementa até 0. O índice
i ainda controla qual posição acessar — só muda a direção.
| i | — |
| v[i] | — |
Padrão 3 — Acumulador (soma e média)
Um acumulador é uma variável iniciada em zero antes do laço. A cada
iteração, o valor v[i] é somado a ela. Ao final do
for, o acumulador contém a soma de todos os elementos.
| i | — |
| soma | 0 |
Padrão 4 — Menor e maior valor
Para encontrar o maior (ou menor) valor, guarda-se o primeiro elemento como candidato inicial e percorre-se o resto do array comparando. Sempre que um elemento supera o candidato atual, ele passa a ser o novo campeão.
| i | — |
| max | — |
max = v[0] inicializa com o primeiro elemento. Se o
laço também começasse em i = 0, compararia
v[0] > max, o que é sempre falso — desperdício de
uma iteração. Começar em i = 1 evita essa comparação
redundante.
Padrão 5 — Preencher com ReadLine
Nos exercícios reais os valores virão do usuário. O padrão é:
primeiro ler o tamanho, criar o array, depois usar um for
para preencher cada posição com Console.ReadLine().
| n | — |
| i | — |
new int[n] precisa do valor de n, que
só é conhecido após a leitura na linha 2. Por isso a declaração
do array vem depois do Console.ReadLine() —
ao contrário de arrays com tamanho fixo, que podem ser declarados
no início do programa.
Dois vetores paralelos
Usando o mesmo índice para relacionar dois arrays
Às vezes precisamos guardar dois tipos de informação relacionados: por
exemplo, o nome de cada pessoa e sua idade.
A solução com arrays paralelos usa dois vetores distintos onde a posição
i de um corresponde exatamente à posição i do outro.
Declaração e diagrama
string[] nomes = { "Ana", "Bruno", "Carla", "Diego" };
int[] idades = { 22, 19, 25, 21 };
// nomes[i] e idades[i] pertencem à mesma pessoa
for (int i = 0; i < nomes.Length; i++)
{
Console.WriteLine($"{nomes[i]} tem {idades[i]} anos.");
}
O diagrama abaixo mostra a correspondência entre os dois arrays.
Clique em Próximo para ver o cursor i
percorrer ambas as linhas ao mesmo tempo.
Regra: os dois arrays devem ter o mesmo tamanho
-
nomes[i]
Nome da pessoa na posição
i. Os arrays têm o mesmo tamanho, então oforemnomes.Lengthpercorre ambos. -
idades[i]
Idade da mesma pessoa.
nomes[i]eidades[i]são inseparáveis — posição é o vínculo entre eles. -
nomes.Length
Usado como limite do
for. Como os dois arrays têm o mesmo tamanho, basta verificar um deles.
Em arrays paralelos, o índice i é a chave de
relacionamento: nomes[i] e
idades[i] pertencem sempre à mesma pessoa.
Se você mudar a ordem de um array sem mudar a do outro, os dados
ficam dessincronizados e o programa produz resultados errados.
Arrays paralelos funcionam bem para problemas pequenos e bem
definidos. Quando os dados se tornam mais complexos — muitos campos
por entidade, necessidade de ordenação conjunta — a solução mais
robusta em C# é usar classes (que agrupam
nome e idade numa mesma estrutura).
Você verá isso em breve.


