C# Arrays

A Ana dá aula para uma turma de 5 alunos e quer guardar as notas. Com o que você viu até aqui, ela criaria nota1, nota2, nota3, nota4 e nota5. E se a turma tiver 40 alunos? Quarenta variáveis, quarenta Console.WriteLine, e nenhum laço consegue passar por elas, porque cada uma tem um nome diferente. O array (em inglês, "arranjo", "fileira"; em português também se diz vetor ou matriz) resolve isso: uma variável que guarda vários valores do mesmo tipo, um ao lado do outro, cada um com um número de posição.

Você vai aprender
  • Como criar um array: int[] notas = [7, 8, 6, 9, 10]; e new int[5].
  • Por que a primeira posição é a 0, e como ler e trocar um elemento pelo índice.
  • O Length, e como percorrer o array com for e com foreach.
  • As receitas que todo programa usa: somar, tirar a média, achar o maior e procurar.
  • Os valores que um array novo já tem (0, false, null) e como mostrar o array inteiro com string.Join.
  • Por que b = a não copia e a == b não compara os valores.
  • O erro mais comum: o índice que passa do fim, e a IndexOutOfRangeException.

Todos os programas foram rodados com o .NET 10 (dotnet --version = 10.0.112, C# 14) na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/cs, com dotnet run arquivo.cs. Antes desta aula, é bom ter visto o for e o foreach: arrays e laços andam sempre juntos.


A ideia: a fileira de armários numerados

Pense nos armários de um vestiário: uma fileira de portinhas iguais, coladas uma na outra. A fileira tem um nome ("armários da turma B") e cada portinha tem um número. Para guardar ou pegar alguma coisa, você não precisa de um nome novo para cada armário: diz "armário 3 da turma B".

Um array é exatamente isso:

  • a fileira inteira tem um nome: notas;
  • todas as portinhas guardam o mesmo tipo de coisa: int, por exemplo;
  • cada portinha tem um número de posição, o índice, escrito entre colchetes: notas[3];
  • o número de portinhas é decidido quando a fileira é construída e não muda depois.

Só tem uma surpresa: a contagem das portinhas começa no 0, não no 1. Já já você vê o porquê.


1. O primeiro array

int[] notas = [7, 8, 6, 9, 10];
Console.WriteLine($"Primeira nota: {notas[0]}");
Console.WriteLine($"Terceira nota: {notas[2]}");
Console.WriteLine($"Última nota: {notas[4]}");
Console.WriteLine($"Quantas notas: {notas.Length}");
int[]
O tipo: "array de int". Os colchetes vazios depois do tipo dizem que não é um int só, e sim uma fileira deles. Todos os elementos são int: um array não mistura tipos.
notas
O nome do array, com as regras de qualquer variável (aula Nomes e Convenções). Costuma ir no plural: notas, precos, alunos.
= [7, 8, 6, 9, 10]
Os valores iniciais, entre colchetes, separados por vírgula, na ordem das posições. Isso se chama expressão de coleção C# 12. O compilador conta os valores: o array tem 5 elementos.
notas[0]
Depois de criado, o número entre colchetes ao lado do nome é o índice, a posição que você quer. notas[0] é o primeiro elemento, que vale 7.
notas[4]
O último. Num array de 5, as posições vão de 0 a 4.
notas.Length
"Comprimento": quantos elementos o array tem. Vale 5, e nunca muda.
$ dotnet run notas.cs
Primeira nota: 7
Terceira nota: 6
Última nota: 10
Quantas notas: 5

2. Por que o índice começa em 0

O índice não é "o número do armário" no sentido de contagem humana. Ele é a distância desde o começo da fileira: o primeiro elemento está a 0 passos do começo, o segundo a 1 passo, e assim por diante.

Índice[0][1][2][3][4]
Valor786910
Passos desde o começo01234
Para a Anaaluno 1aluno 2aluno 3aluno 4aluno 5

Na memória, os 5 inteiros ficam colados. Para achar notas[3], o computador faz uma conta só: "começo da fileira + 3 elementos". Por isso acessar qualquer posição é igualmente rápido, seja a primeira ou a milésima. Quase todas as linguagens (C, Java, JavaScript, Python) contam do 0 pelo mesmo motivo.

A consequência que você vai usar o tempo todo: num array de N elementos, os índices vão de 0 a N−1. O último elemento é sempre notas[notas.Length - 1]. (Há um atalho para ele, notas[^1], na aula Índices e Intervalos.)

Missão: complete o segundo WriteLine para mostrar a nota do segundo aluno, Segunda nota: 8. Qual é o índice do segundo elemento?

Primeira nota: 7
Segunda nota: 8
int[] notas = [7, 8, 6, 9, 10];
Console.WriteLine($"Primeira nota: {notas[0]}");
Console.WriteLine($"Segunda nota: {0}");   // troque o 0 pelo elemento certo
int[] notas = [7, 8, 6, 9, 10];
Console.WriteLine($"Primeira nota: {notas[0]}");
Console.WriteLine($"Segunda nota: {notas[1]}");

3. Trocar um elemento

Cada elemento funciona como uma variável comum: recebe valor com = e entra em contas.

int[] notas = [7, 8, 6, 9, 10];
Console.WriteLine($"Antes: notas[2] = {notas[2]}");
notas[2] = 10;
notas[0]++;
Console.WriteLine($"Depois: notas[2] = {notas[2]}");
Console.WriteLine($"E notas[0] = {notas[0]}");
notas[2] = 10;
O terceiro aluno fez a recuperação: a portinha 2 recebe 10. O 6 que estava lá some.
notas[0]++;
Um ponto extra para o primeiro aluno: o 7 vira 8 (aula ++ e --). Também valeria notas[0] += 1;.
$ dotnet run trocar.cs
Antes: notas[2] = 6
Depois: notas[2] = 10
E notas[0] = 8

O índice pode ser uma variável

Entre os colchetes pode ir qualquer conta que dê um int: notas[i], notas[i + 1], notas[notas.Length - 1]. É isso que deixa o array poderoso: um laço faz i valer 0, 1, 2, 3, 4, e notas[i] passa por todos os elementos. O índice tem de ser inteiro: com double i = 1;, o notas[i] dá error CS0266: Não é possível converter implicitamente tipo "double" em "int". Não existe a portinha 1,5.


4. Percorrer o array

Com for

O for (int i = 0; i < notas.Length; i++) dá exatamente os índices do array: 0, 1, 2, 3 e 4. Com ele, a Ana mostra todas as notas e calcula a média:

int[] notas = [7, 8, 6, 9, 10];
int soma = 0;
for (int i = 0; i < notas.Length; i++)
{
    Console.WriteLine($"Aluno {i + 1}: nota {notas[i]}");
    soma += notas[i];
}
Console.WriteLine($"Soma: {soma}");
Console.WriteLine($"Média: {soma / (double)notas.Length}");
i < notas.Length
Começa no 0 e usa <: passa por 0, 1, 2, 3, 4 e para antes do 5. Usar o Length (em vez de escrever 5) faz o laço continuar certo se a turma crescer.
i + 1
Para a Ana, o aluno [0] é o "aluno 1". Na tela, a contagem humana; no código, o índice.
soma += notas[i];
A cada volta, soma o elemento da posição i.
soma / (double)notas.Length
Converter um dos lados para double faz a divisão ter casas decimais (aula Conversão de Tipos). Sem isso, 39 / 5 daria 7, e não 7,8.
$ dotnet run percorre.cs
Aluno 1: nota 7
Aluno 2: nota 8
Aluno 3: nota 6
Aluno 4: nota 9
Aluno 5: nota 10
Soma: 40
Média: 8

Se a turma crescer para 40 alunos, só a primeira linha muda. É para isso que o array existe.

Com foreach

Quando você só precisa dos valores, e não da posição, o foreach ("para cada") é mais simples: não tem índice, não tem condição, e não tem como passar do fim.

string[] compras = ["arroz", "feijão", "café"];
foreach (string item in compras)
{
    Console.WriteLine($"- {item}");
}
$ dotnet run foreach-arr.cs
- arroz
- feijão
- café

Mas o foreach só lê. Tentar mudar o elemento por ele não compila:

$ cat foreach-muda.cs
int[] notas = [7, 8, 6];
foreach (int nota in notas)
{
    nota = nota + 1;
}
$ dotnet run foreach-muda.cs
/home/ana/cs/foreach-muda.cs(4,5): error CS1656: Não é possível atribuir a "nota" porque ele é um "variável de iteração foreach"

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

A nota é uma cópia do valor de cada portinha, e o C# não deixa mudá-la, justamente para ninguém achar que mudou o array. Para mudar os elementos, use o for com índice: notas[i] = notas[i] + 1;.

UseQuando
foreach (int n in notas)Só ler os valores, do primeiro ao último. O mais simples e o mais seguro.
for (int i = 0; i < notas.Length; i++)Você precisa da posição (mostrar "aluno 3", lembrar onde estava o maior), quer mudar os elementos, ou percorrer de outro jeito (de trás para a frente, de 2 em 2).

Missão: a Ana quer saber quantos alunos passaram (nota 7 ou mais). Dentro do laço, some 1 em aprovados quando a nota for maior ou igual a 7. O resultado tem de ser Aprovados: 3. Aqui, for ou foreach: você escolhe.

Aprovados: 3
int[] notas = [7, 4, 9, 6, 8];
int aprovados = 0;
foreach (int nota in notas)
{
    // se a nota for 7 ou mais, conte mais um aprovado

}
Console.WriteLine($"Aprovados: {aprovados}");
int[] notas = [7, 4, 9, 6, 8];
int aprovados = 0;
foreach (int nota in notas)
{
    if (nota >= 7)
    {
        aprovados++;
    }
}
Console.WriteLine($"Aprovados: {aprovados}");

5. Duas receitas que todo programa usa

Além de acumular (a soma, que você já viu), quase todo programa com array precisa achar o maior ou procurar um valor.

Achar o maior

A Ana anotou os pontos de 6 rodadas de um jogo e quer o recorde:

int[] pontos = [12, 45, 7, 45, 30, 18];
int maior = pontos[0];
int posicao = 0;
for (int i = 1; i < pontos.Length; i++)
{
    if (pontos[i] > maior)
    {
        maior = pontos[i];
        posicao = i;
    }
}
Console.WriteLine($"Maior pontuação: {maior} (rodada {posicao + 1})");
int maior = pontos[0];
O "campeão provisório" é o primeiro elemento. Não comece com maior = 0: se todos os valores fossem negativos (temperaturas no inverno da Sibéria), o 0 ganharia sem estar no array.
for (int i = 1; …)
Começa no 1, porque o elemento 0 já é o campeão.
if (pontos[i] > maior)
Achou alguém maior? Ele vira o novo campeão, e posicao guarda onde estava.
> e não >=
O 45 aparece duas vezes (rodadas 2 e 4). Com >, o empate não troca o campeão, e fica a primeira vez.
$ dotnet run maior.cs
Maior pontuação: 45 (rodada 2)

Procurar um valor

Na lojinha da Ana, cada produto tem um código. O 330 está cadastrado? Em que posição?

int[] codigos = [101, 205, 330, 412, 587];
int procurado = 330;
int achou = -1;
for (int i = 0; i < codigos.Length; i++)
{
    if (codigos[i] == procurado)
    {
        achou = i;
        break;
    }
}
if (achou >= 0)
{
    Console.WriteLine($"Código {procurado} está na posição {achou}");
}
else
{
    Console.WriteLine($"Código {procurado} não existe");
}
int achou = -1;
−1 não é um índice válido. Por isso ele serve de sinal: "ainda não achei".
break;
Achou: não precisa olhar o resto (aula break e continue).
$ dotnet run procura.cs
Código 330 está na posição 2

Essas receitas são tão comuns que o .NET já as traz prontas: Array.IndexOf(codigos, 330) faz a busca, Array.Sort ordena (aula A Classe Array), e notas.Max(), notas.Sum() e notas.Average() vêm do LINQ (aula Agregar). Mas vale saber fazer à mão: é o mesmo raciocínio que você vai usar para coisas que não vêm prontas.


6. As formas de criar um array

int[] a = [1, 2, 3];
int[] b = { 1, 2, 3 };
int[] c = new int[] { 1, 2, 3 };
int[] d = new int[3];
var e = new[] { 1, 2, 3 };
int[] f = [];
Console.WriteLine(string.Join(" ", a));
Console.WriteLine(string.Join(" ", b));
Console.WriteLine(string.Join(" ", c));
Console.WriteLine(string.Join(" ", d));
Console.WriteLine(string.Join(" ", e));
Console.WriteLine($"f tem {f.Length} elementos");
$ dotnet run formas.cs
1 2 3
1 2 3
1 2 3
0 0 0
1 2 3
f tem 0 elementos
int[] a = [1, 2, 3];
Expressão de coleção C# 12: a forma moderna, e a que o guia usa. Os mesmos colchetes servem para criar listas e outras coleções (aula List<T>).
int[] b = { 1, 2, 3 };
Com chaves: a forma clássica, que existe desde o C# 1. Você vai ver muito em código e cursos mais antigos. Só funciona na linha em que a variável é criada.
int[] c = new int[] { 1, 2, 3 };
A forma completa, com new ("novo"). Também antiga.
int[] d = new int[3];
Um array de 3 elementos, ainda sem valores escolhidos: todos começam com o valor padrão do tipo, que no int é 0 (seção 7). Use quando você sabe o tamanho, mas os valores vêm depois (do teclado, de uma conta).
var e = new[] { 1, 2, 3 };
O compilador descobre o tipo pelos valores: int[]. Pouco usado hoje.
int[] f = [];
Um array vazio, com 0 elementos. Existe e tem Length 0; só não tem portinha nenhuma.

Qual usar

SituaçãoForma
Você já sabe os valoresint[] notas = [7, 8, 6];
Você sabe o tamanho, os valores vêm depoisint[] notas = new int[40];
Começar vazioint[] notas = [];
Código antigo (antes do C# 12){ 7, 8, 6 } ou new int[] { 7, 8, 6 }: leia sem susto, é o mesmo array

Encher o array pelo teclado

Com new int[3] e um for, a Ana lê as notas com o Console.ReadLine da aula Ler do Teclado:

int[] notas = new int[3];
for (int i = 0; i < notas.Length; i++)
{
    Console.Write($"Nota do aluno {i + 1}: ");
    if (!int.TryParse(Console.ReadLine(), out notas[i]))
    {
        Console.WriteLine("Nota inválida.");
        return;
    }
}
Console.WriteLine($"Você digitou: {string.Join(", ", notas)}");
$ dotnet run ler.cs
Nota do aluno 1: 8
Nota do aluno 2: 7
Nota do aluno 3: 10
Você digitou: 8, 7, 10
out notas[i]
O TryParse guarda o número direto na portinha i. Um elemento de array funciona em qualquer lugar onde uma variável funcionaria.

7. O que um array novo já tem

Em C#, as portinhas de um new int[3] nunca têm "lixo": cada uma começa com o valor padrão do tipo.

int[] inteiros = new int[3];
decimal[] precos = new decimal[3];
bool[] presencas = new bool[3];
string[] nomes = new string[3];
Console.WriteLine($"int:     [{string.Join(", ", inteiros)}]");
Console.WriteLine($"decimal: [{string.Join(", ", precos)}]");
Console.WriteLine($"bool:    [{string.Join(", ", presencas)}]");
Console.WriteLine($"string:  [{string.Join(", ", nomes)}]");
Console.WriteLine(nomes[0] is null);
Console.WriteLine(nomes[0].Length);
$ dotnet run padrao.cs
int:     [0, 0, 0]
decimal: [0, 0, 0]
bool:    [False, False, False]
string:  [, , ]                 « três nada: as portinhas têm null
True
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at Program.<Main>$(String[] args) in /home/ana/cs/padrao.cs:line 10
Tipo do elementoValor padrão
int, long, double, decimal…0
boolfalse
charo caractere de código 0 (invisível)
string e outros tipos de referêncianull
Pegadinha: o new string[3] está cheio de null, e o compilador não avisa

O tipo é string[], sem ?, mas as portinhas começam com null. As referências anuláveis (aula Referências Anuláveis) não conferem os elementos de um array: o nomes[0].Length compilou sem nenhum aviso e quebrou com NullReferenceException ao rodar (código 134). Com arrays de texto, prefira dar os valores na criação (["Ana", "Bia", "Caio"]) ou encher todas as posições antes de usar.


8. Mostrar o array inteiro

Parece natural passar o array direto para o WriteLine. Não dá certo:

int[] notas = [7, 8, 6, 9, 10];
Console.WriteLine(notas);
Console.WriteLine(string.Join(", ", notas));
Console.WriteLine($"Notas: [{string.Join(" | ", notas)}]");
$ dotnet run imprimir.cs
System.Int32[]
7, 8, 6, 9, 10
Notas: [7 | 8 | 6 | 9 | 10]

O Console.WriteLine(notas) mostra só o nome do tipo: System.Int32[] ("array de Int32", que é o nome completo do int). Para ver os valores, use string.Join(separador, array), que "junta" todos os elementos num texto só, com o separador entre eles (aula Métodos de String).


9. b = a não copia, e a == b não compara

Com variáveis de tipos simples, como int, b = a copia o valor. Com arrays, é diferente: a variável não guarda a fileira em si, e sim o endereço dela, como um papelzinho dizendo "os armários ficam no corredor 3". Isso se chama tipo de referência (aula Valor × Referência).

Duas variáveis, o mesmo array

int[] a = [7, 8, 9];
int[] b = a;
b[0] = 100;
Console.WriteLine($"a: {string.Join(" ", a)}");
Console.WriteLine($"b: {string.Join(" ", b)}");
$ dotnet run copiar.cs
a: 100 8 9          « o a mudou também!
b: 100 8 9

O b = a copiou o papelzinho, não os armários. Agora a e b apontam para a mesma fileira: mudar por um muda o que o outro vê. Para uma cópia de verdade, crie um array novo com os mesmos elementos. O .. dentro dos colchetes "espalha" os elementos de a no array novo C# 12:

int[] a = [7, 8, 9];
int[] b = [.. a];
b[0] = 100;
Console.WriteLine($"a: {string.Join(" ", a)}");
Console.WriteLine($"b: {string.Join(" ", b)}");
$ dotnet run copiar2.cs
a: 7 8 9
b: 100 8 9          « agora sim, duas fileiras

Em código mais antigo, você vai ver a cópia feita com (int[])a.Clone() ou Array.Copy (aula A Classe Array). O resultado é o mesmo.

Comparar

int[] a = [7, 8, 9];
int[] b = [7, 8, 9];
Console.WriteLine(a == b);
Console.WriteLine(a.Equals(b));
Console.WriteLine(a.SequenceEqual(b));
$ dotnet run comparar.cs
False               « os valores são iguais, mas são duas fileiras
False
True

O == (e o Equals) pergunta "é o mesmo array?", e não "têm os mesmos valores?". São duas fileiras diferentes, então a resposta é False. Para comparar os valores, um por um, na ordem, use a.SequenceEqual(b) ("sequência igual"), que vem do LINQ (aula O que é LINQ) e já está disponível nos programas de arquivo único.


10. O índice que passa do fim

Agora o erro mais importante desta aula. Este é o erro do "um a mais" da aula for, agora com um array: <= no lugar de <.

int[] notas = [7, 8, 6, 9, 10];
int soma = 0;
for (int i = 0; i <= notas.Length; i++)
{
    soma += notas[i];
}
Console.WriteLine($"Soma: {soma}");
$ dotnet run fora.cs                « compilou sem nenhum aviso
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Program.<Main>$(String[] args) in /home/ana/cs/fora.cs:line 5
$ echo $?
134
Unhandled exception
"Exceção não tratada": o programa encontrou um problema que ninguém tratou e parou ali (aula Exceções). O Soma: nem chegou a aparecer.
System.IndexOutOfRangeException
"Exceção de índice fora do intervalo". O nome já diz o problema.
Index was outside the bounds of the array.
"O índice estava fora dos limites do array." Quando i chegou a 5, o notas[5] pediu a sexta portinha de uma fileira de cinco.
at Program.<Main>$(String[] args) in /home/ana/cs/fora.cs:line 5
Onde aconteceu: no arquivo fora.cs, linha 5, a do soma += notas[i];. O <Main>$ é o nome que o C# dá ao Main escondido das instruções de nível superior.
134
O código de saída de um programa que terminou com exceção, no Linux. Um script percebe que algo deu errado.

A boa notícia: o C# confere todo índice, sempre. Ele nunca lê nem escreve fora do array em silêncio (como o C faz): para o programa na hora, e diz a linha. O conserto é trocar o <= por <, ou usar o foreach, que não tem como passar do fim.

Regra do guia: todo índice fica entre 0 e Length - 1

Percorra com for (int i = 0; i < v.Length; i++), com <, ou com foreach. Se o índice vem de fora (do teclado, dos argumentos, de uma conta), confira antes de usar: if (i >= 0 && i < v.Length).


Quando dá errado

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.

O que significa: um índice foi negativo ou chegou a Length (ou passou). Quase sempre é um <= no laço, um v[v.Length] no lugar de v[v.Length - 1], ou um índice que veio de fora sem conferir. O programa termina com o código 134.

Como consertar: olhe a linha que a mensagem aponta (line 5). Use < nos laços, foreach quando puder, e confira índices de fora com if.

error CS0650 e error CS0270: o array do jeito do C
$ cat estilo-c.cs
int notas[5];
$ dotnet run estilo-c.cs
/home/ana/cs/estilo-c.cs(1,10): error CS0650: Declarador de matriz incorreto: para declarar uma matriz gerenciada, o especificador de classificação antecede o identificador de variável. Para declarar um campo de buffer de tamanho fixo, use a palavra-chave fixed antes do tipo de campo.
/home/ana/cs/estilo-c.cs(1,11): error CS0270: O tamanho de matriz não pode ser especificado em uma declaração de variável (tente inicializar com uma expressão 'new')

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: quem vem do C ou do C++ escreve os colchetes depois do nome. Em C#, eles vão depois do tipo ("o especificador de classificação antecede o identificador"), e o tamanho não entra ali: vai no new. O tradutor chama o array de "matriz".

Como consertar: int[] notas = new int[5];.

error CS0029: Não é possível converter implicitamente tipo "string" em "int"

O que significa: um valor de outro tipo entrou na lista, como em int[] notas = [7, 8, "nove"];. Um array de int só aceita int.

Como consertar: escreva o valor do tipo certo (9), ou mude o tipo do array, se a ideia era guardar textos.

error CS0165: Uso de variável local não atribuída "notas"

O que significa: você escreveu int[] notas; e depois notas[0] = 7;. A variável existe, mas a fileira nunca foi construída: não há portinha nenhuma.

Como consertar: crie o array antes de usar: int[] notas = new int[5]; ou int[] notas = [7, 8, 6];.

error CS0847: Inicializador de matriz de comprimento "3" é esperado

O que significa: em new int[3] { 7, 8 }, o tamanho diz 3 e a lista tem 2. Em C#, os dois têm de bater (ao contrário do C, que completaria com zeros).

Como consertar: tire o tamanho e deixe o compilador contar: int[] notas = [7, 8];.

error CS1656: Não é possível atribuir a "nota" porque ele é um "variável de iteração foreach"

O que significa: você tentou mudar a variável do foreach. Ela é só uma cópia de leitura de cada elemento.

Como consertar: use um for com índice e mude notas[i].

error CS1061: ‘int[]’ não contém uma definição para "Add"

O que significa: você tentou acrescentar um elemento com notas.Add(10). O array tem tamanho fixo: não cresce nem diminui.

Como consertar: se a quantidade muda enquanto o programa roda, use uma List<int>, que cresce (aula List<T>). Com array, só criando outro maior: notas = [.. notas, 10];.

Apareceu System.Int32[] em vez dos valores

O que significa: o Console.WriteLine(notas) mostra o nome do tipo, e não os elementos.

Como consertar: Console.WriteLine(string.Join(", ", notas));, ou um foreach.

Mudei um array e o outro mudou junto

O que significa: as duas variáveis apontam para o mesmo array, por causa de um b = a.

Como consertar: faça uma cópia de verdade: int[] b = [.. a];.


Referência rápida

EscritaO que faz
int[] v = [1, 2, 3];Array de 3 int com esses valores (C# 12)
int[] v = { 1, 2, 3 }; / new int[] { 1, 2, 3 }O mesmo, nas formas antigas
int[] v = new int[5];Array de 5, todos com o valor padrão (0)
int[] v = [];Array vazio (0 elementos)
v[0] / v[v.Length - 1]Primeiro e último elemento
v[i] = 10;Troca o elemento da posição i
v.LengthQuantos elementos (fixo)
for (int i = 0; i < v.Length; i++)Percorre com índice
foreach (int x in v)Percorre só lendo os valores
string.Join(", ", v)Texto com todos os elementos
int[] b = [.. a];Cópia de verdade (C# 12)
a.SequenceEqual(b)Compara os valores (o == compara se é o mesmo array)
IndexOutOfRangeExceptionÍndice menor que 0 ou maior que Length - 1 (código 134)

Exercícios

1. O último elemento

Complete para mostrar o último elemento de um array de 7 dias:

Console.WriteLine(dias[]);

2. Percorrer

Complete a condição para percorrer o array precos inteiro, sem passar do fim:

for (int i = 0; ; i++)

3. Criar com tamanho

Complete para criar um array de 20 decimal, todos valendo 0:

decimal[] saldos = ;

4. Depois de bool[] presencas = new bool[4];, quanto vale presencas[2]?

5. O que este programa mostra?

int[] a = [1, 2, 3];
int[] b = a;
b[1] = 50;
Console.WriteLine(a[1]);

6. Um laço com i <= notas.Length roda num array de 5 notas. O que acontece?

7. Por que, ao procurar o maior valor, o "campeão" começa como v[0] e não como 0?

Missão final: as temperaturas da semana

Missão: a Ana anotou a temperatura máxima de cada dia da semana. Complete o programa para mostrar a maior e a menor temperatura, com o dia de cada uma (o dia 1 é temperaturas[0]), e a média com uma casa decimal. Use um laço.

Maior: 32 (dia 7)
Menor: 25 (dia 5)
Média: 28,9
int[] temperaturas = [28, 31, 30, 27, 25, 29, 32];
int maior = 0, diaMaior = 0;
int menor = 0, diaMenor = 0;
int soma = 0;

// percorra o array aqui

Console.WriteLine($"Maior: {maior} (dia {diaMaior})");
Console.WriteLine($"Menor: {menor} (dia {diaMenor})");
Console.WriteLine($"Média: {soma / (double)temperaturas.Length:F1}");
int[] temperaturas = [28, 31, 30, 27, 25, 29, 32];
int maior = temperaturas[0], diaMaior = 1;
int menor = temperaturas[0], diaMenor = 1;
int soma = 0;

for (int i = 0; i < temperaturas.Length; i++)
{
    if (temperaturas[i] > maior)
    {
        maior = temperaturas[i];
        diaMaior = i + 1;
    }
    if (temperaturas[i] < menor)
    {
        menor = temperaturas[i];
        diaMenor = i + 1;
    }
    soma += temperaturas[i];
}

Console.WriteLine($"Maior: {maior} (dia {diaMaior})");
Console.WriteLine($"Menor: {menor} (dia {diaMenor})");
Console.WriteLine($"Média: {soma / (double)temperaturas.Length:F1}");

A solução faz as receitas da seção 5 num laço só. O menor também começa com o primeiro elemento: se começasse com 0, nenhuma temperatura seria menor que ele, e a resposta sairia Menor: 0, que nem está no array. A soma é 202, e 202 ÷ 7 = 28,857…, que o :F1 (uma casa decimal, aula Formatar Números) arredonda para 28,9, com vírgula, porque o notebook da Ana está em português.


Resumo

  • Um array guarda vários valores do mesmo tipo com um nome só: int[] notas = [7, 8, 6];. O tamanho é fixo depois de criado e fica em notas.Length.
  • O índice começa em 0: num array de N, as posições vão de 0 a N−1. Cada elemento (notas[i]) funciona como uma variável comum.
  • Percorra com for (int i = 0; i < v.Length; i++) quando precisar da posição ou for mudar os elementos, e com foreach para só ler.
  • new int[5] cria 5 elementos com o valor padrão: 0, false, ou null para string (sem aviso do compilador).
  • Para mostrar, string.Join(", ", v); o WriteLine(v) mostra só System.Int32[].
  • Arrays são de referência: b = a faz as duas variáveis apontarem para o mesmo array, e a == b pergunta se é o mesmo array. Copie com [.. a] e compare com SequenceEqual.
  • O C# confere todo índice: passar do fim dá IndexOutOfRangeException, com a linha do erro e o código de saída 134.