Contadores e acumuladores
Diferencie contadores e acumuladores, acompanhe resultados parciais e inicialize corretamente soma, produto, média, mínimo e máximo.

Contador responde “quantos”; acumulador constrói um resultado
Contadores e acumuladores são variáveis que preservam estado entre iterações, mas cumprem papéis diferentes:
- um contador registra quantas vezes um evento ocorreu, normalmente adicionando uma unidade;
- um acumulador combina cada novo valor com um resultado parcial, como em uma soma, produto ou concatenação.
Considere cinco valores hipotéticos de vendas:
120, -15, 80, 0, 200
Neste exemplo, somente valores maiores que zero representam vendas concluídas. Queremos descobrir:
- quantas vendas foram concluídas;
- qual foi o valor total dessas vendas;
- qual foi o valor médio por venda concluída.
O contador responderá “quantas”; o acumulador responderá “quanto foi combinado”.
Três variáveis podem mudar sem exercer o mesmo papel
Um algoritmo que percorre os cinco valores com um laço for pode usar:
quantidadeValidas <- 0
total <- 0
PARA CADA valor EM vendas FAÇA
SE valor > 0 ENTÃO
quantidadeValidas <- quantidadeValidas + 1
total <- total + valor
FIM SE
FIM PARA
Se a linguagem exigir uma posição explícita, pode existir também posicao. Essa variável controla qual item será visitado. Ela não representa necessariamente um resultado do problema.
Compare os papéis:
| Variável | Papel | Atualização |
|---|---|---|
posicao | controle do percurso | avança para cada item |
quantidadeValidas | contador do domínio | soma 1 somente para venda válida |
total | acumulador | incorpora o valor da venda válida |
Um contador de laço e um contador de negócio podem terminar com valores diferentes. O percurso visita cinco registros, mas apenas três satisfazem valor > 0.
Ambos podem ser vistos como formas de acumulação de estado. A distinção é útil porque torna a intenção visível: contar ocorrências é um caso especializado, enquanto acumular pode empregar diferentes operações e tipos de valor.
Inicialize antes de começar a repetição
O estado deve existir antes da primeira passagem:
quantidadeValidas <- 0
total <- 0
Zero representa corretamente o resultado quando nenhuma venda foi processada. Também não altera a primeira adição:
0 + 120 = 120
Reinicializar dentro do corpo destrói o histórico:
PARA CADA valor EM vendas FAÇA
total <- 0
total <- total + valor
FIM PARA
Ao fim, total conserva apenas o efeito da última passagem. O valor parcial anterior é substituído por zero antes que o próximo item seja incorporado.
Esse erro pode passar despercebido quando o teste usa apenas um item. Casos com zero, um e vários itens revelam responsabilidades diferentes da inicialização.
Atualize somente quando o evento ou valor pertence ao resultado
A estrutura condicional determina quais itens participam:
SE valor > 0 ENTÃO
quantidadeValidas <- quantidadeValidas + 1
total <- total + valor
FIM SE
As duas atualizações precisam estar sob a mesma regra neste problema. Se o contador fosse incrementado para todos os registros e o total somente para os positivos, a média dividiria o valor correto por uma quantidade incompatível.
O rastreamento completo fica assim:
| Item | valor > 0 | quantidadeValidas depois | total depois |
|---|---|---|---|
| 120 | verdadeiro | 1 | 120 |
| -15 | falso | 1 | 120 |
| 80 | verdadeiro | 2 | 200 |
| 0 | falso | 2 | 200 |
| 200 | verdadeiro | 3 | 400 |
“Não atualizar” também é uma decisão de estado. Depois de -15, quantidade e total continuam representando apenas as vendas válidas já vistas.
Use invariantes para explicar o resultado parcial
Uma invariante do laço é uma afirmação que permanece verdadeira em pontos equivalentes da repetição. Depois de processar qualquer quantidade de itens do exemplo:
quantidadeValidasé o número de valores positivos já processados;totalé a soma dos valores positivos já processados.
Antes do primeiro item, ambas são verdadeiras: nenhum valor positivo foi visto, então quantidade e soma são zero.
Quando chega um valor inválido, nenhuma variável muda e as afirmações continuam verdadeiras. Quando chega um valor válido, somar uma unidade à quantidade e o próprio valor ao total preserva as duas afirmações.
Ao terminar o percurso, “itens já processados” significa a sequência inteira. As invariantes se transformam nas propriedades desejadas do resultado final.
Essa verificação é mais forte do que conferir apenas 3 e 400: ela explica por que o algoritmo funciona para outras sequências.
Calcule a média somente quando existe denominador
A média depende dos dois resultados:
SE quantidadeValidas > 0 ENTÃO
media <- total / quantidadeValidas
EXIBIR media
SENÃO
EXIBIR "Nenhuma venda válida"
FIM SE
Para o exemplo:
media = 400 / 3
media ≈ 133,33
Não divida pelo número total de registros, pois os valores inválidos não entraram na soma. Também não divida antes de confirmar que quantidadeValidas é maior que zero.
Calcular a média dentro de cada passagem produziria médias parciais. Isso pode ser desejado para acompanhar evolução, mas é trabalho desnecessário quando apenas o resultado final importa.
Em um sistema real, tipo numérico e arredondamento de valores monetários precisam seguir a regra do domínio. Aqui usamos inteiros para concentrar a explicação no padrão de estado.
O valor inicial depende da operação
Zero funciona para soma e contagem, mas não para todo acumulador. O valor inicial deve representar o resultado antes de receber itens e não distorcer a primeira combinação.
| Objetivo | Inicialização comum | Atualização |
|---|---|---|
| contar ocorrências | 0 | quantidade + 1 |
| somar valores | 0 | total + valor |
| multiplicar valores | 1 | produto * valor |
| concatenar texto | texto vazio | texto + parte |
| verificar se algum atende | falso | algum OU condicao |
| verificar se todos atendem | verdadeiro | todos E condicao |
Esses valores são neutros para as respectivas operações: combinar um valor com eles mantém o valor.
0 + x = x
1 * x = x
falso OU x = x
verdadeiro E x = x
Usar zero para um produto faria qualquer resultado permanecer zero. Iniciar “todos atendem” com falso impediria que o acumulador se tornasse verdadeiro usando E.
Mínimo e máximo exigem presença explícita
Para encontrar o maior valor, iniciar com zero falha quando todos os valores válidos são negativos. O algoritmo devolveria zero mesmo que ele nunca aparecesse na entrada.
Uma estratégia segura é representar a ausência até encontrar o primeiro item válido:
maior <- AUSENTE
PARA CADA valor EM valores FAÇA
SE valor for válido ENTÃO
SE maior está AUSENTE OU valor > maior ENTÃO
maior <- valor
FIM SE
FIM SE
FIM PARA
Depois do laço:
- se
maiorcontinua ausente, não havia valor válido; - caso contrário, ele contém o maior valor encontrado.
Outra possibilidade é inicializar com o primeiro valor válido e percorrer os restantes. As duas estratégias obrigam o algoritmo a tratar a sequência vazia, em vez de inventar um número que pareça pequeno ou grande o bastante.
Constantes como infinito positivo ou negativo podem ser adequadas em contextos numéricos específicos, mas não generalizam para textos, datas ou tipos próprios. Presença explícita comunica melhor a ausência de resultado.
Implemente o exemplo em JavaScript e Python
JavaScript
const vendas = [120, -15, 80, 0, 200];
let quantidadeValidas = 0;
let total = 0;
for (const valor of vendas) {
if (valor > 0) {
quantidadeValidas += 1;
total += valor;
}
}
const media = quantidadeValidas > 0
? total / quantidadeValidas
: null;
console.log({ quantidadeValidas, total, media });
Resultado aproximado:
{ quantidadeValidas: 3, total: 400, media: 133.333... }
Python
vendas = [120, -15, 80, 0, 200]
quantidade_validas = 0
total = 0
for valor in vendas:
if valor > 0:
quantidade_validas += 1
total += valor
media = total / quantidade_validas if quantidade_validas > 0 else None
print(quantidade_validas, total, media)
O padrão independe da sintaxe: inicializar antes, percorrer, selecionar, atualizar e interpretar o resultado depois.
APIs como reduce também descrevem uma redução em que um resultado parcial recebe o próximo elemento. Entender o laço explícito primeiro ajuda a escolher um valor inicial correto e a depurar versões mais abstratas.
Diagnostique pelos resultados que não podem acontecer
O total contém apenas o último valor
Provavelmente o acumulador foi reinicializado dentro do laço ou recebeu total <- valor em vez de total <- total + valor.
A quantidade é maior que o número de válidos
O contador pode estar fora da condição ou ser incrementado mais de uma vez na mesma passagem.
A média está menor do que deveria
Confira se soma e quantidade usam exatamente o mesmo critério de inclusão.
O produto permanece zero
A inicialização provavelmente usou o neutro da soma em uma multiplicação.
O maior valor é zero sem existir zero na entrada
Um sentinela arbitrário entrou no resultado. Use ausência explícita ou o primeiro item válido.
O caso vazio causa divisão ou resultado inventado
Defina antes o significado da ausência: zero, texto vazio, falso, verdadeiro, valor ausente ou erro podem ser respostas diferentes, conforme a operação e o domínio.
Teste o estado, não apenas a última saída
Inclua pelo menos:
- sequência vazia;
- um item válido;
- um item inválido;
- mistura de válidos e inválidos;
- todos inválidos;
- valores negativos quando forem permitidos;
- primeiro e último itens válidos;
- repetição do mesmo valor.
Faça um teste de mesa e confira as invariantes depois de cada passagem. Para a média, verifique separadamente soma, quantidade e decisão sobre divisão.
Pratique com tempos de atendimento
Considere:
12, 0, 8, 15, -1, 10
Valores positivos representam atendimentos concluídos. Construa um algoritmo que produza:
- quantidade de atendimentos válidos;
- soma dos tempos;
- média dos tempos válidos;
- maior tempo válido, ou ausência quando não houver nenhum.
Registre o estado após cada item e escreva três invariantes: uma para quantidade, outra para soma e outra para maior valor. Teste também uma sequência vazia, somente valores inválidos e [-5, -2] sob duas regras diferentes: negativos inválidos e negativos permitidos.
O que você deve guardar
Um contador registra quantas ocorrências atendem a uma regra. Um acumulador combina valores e conserva um resultado parcial. Ambos precisam ser inicializados antes da repetição e atualizados somente quando o item pertence ao resultado.
Escolha o valor inicial pela operação e pelo significado do caso vazio; não confunda posição do percurso com quantidade do domínio; proteja médias contra divisão por zero; e trate mínimo e máximo sem sentinelas inventadas. Em seguida, aprenda a criar condições de parada e diagnosticar laços infinitos acompanhando como o estado se aproxima da saída.
Referências
- James Madison University — Accumulators, Patterns for Beginning Programmers. Acesso em 11 set. 2026.
- Runestone Academy — The Accumulator Pattern. Acesso em 11 set. 2026.
- Oracle — Reduction, Java Tutorials. Acesso em 11 set. 2026.
- MDN Web Docs —
Array.prototype.reduce(). Acesso em 11 set. 2026.