Skip to content
Fase 3Decisões & Repetições

Controlo de Fluxo

Progresso da fase0%

A carregar…

Nesta fase, o pseudocódigo SE/SENÃO e ENQUANTO da Fase 1 ganha finalmente sintaxe real. Vais aprender if/else, else if, switch, e as duas formas de repetição mais usadas em JavaScript: for e while. No final, conseguirás escrever qualquer decisão ou repetição que consigas descrever em português.

Prompt recomendado para esta fase

Estou na Fase 3 a aprender if/else, switch e loops (for/while) em JavaScript. Quando eu te mostrar um problema, pergunta-me primeiro se já pensei nele em pseudocódigo. Se eu tiver um bug num loop, não corrijas logo — pergunta-me quantas vezes acho que o loop está a correr e ajuda-me a descobrir sozinho onde a contagem falha.

Conteúdos teóricos

5 temas

1. if / else: a primeira decisão em código

A tradução direta do SE/SENÃO que já escreveste em pseudocódigo na Fase 1.

O if executa um bloco de código apenas se uma condição for verdadeira. O else, opcional, executa um bloco alternativo quando a condição é falsa.

javascript
const idade = 20;

if (idade >= 18) {
  console.log("Podes entrar.");
} else {
  console.log("Ainda não tens idade suficiente.");
}

Repara na estrutura: if (condição) seguido de chavetas { } com o código a executar quando a condição for verdadeira. O else também tem as suas próprias chavetas, para o caso contrário.

As chavetas não são opcionais na prática

Tecnicamente, o JavaScript permite omitir as chavetas se só tiveres uma linha de código dentro do if. Não faças isto. É a causa clássica de um bug: alguém adiciona uma segunda linha ao bloco mais tarde, esquece-se de acrescentar as chavetas, e essa segunda linha passa a correr sempre, esteja a condição verdadeira ou não. Escreve sempre as chavetas, mesmo com uma linha só — o teu eu do futuro agradece.

if sem else

Nem toda a decisão precisa de um caminho alternativo. Se não houver nada a fazer quando a condição for falsa, simplesmente omite o else:

javascript
const stock = 0;
if (stock === 0) {
  console.log("Aviso: sem stock!");
}
// o programa continua normalmente, com ou sem o aviso
if-else.js
const temperatura = 15;

if (temperatura < 10) {
  console.log("Está frio, veste um casaco.");
} else {
  console.log("Temperatura razoável.");
}
Decisão simples com dois caminhos

2. else if e switch: mais de dois caminhos

Como lidar com três, quatro ou mais opções, sem encadear if dentro de if de forma ilegível.

Quando há mais de duas opções, usa else if para as encadear numa cadeia legível, testada de cima para baixo até uma condição ser verdadeira:

javascript
const nota = 14;

if (nota >= 18) {
  console.log("Excelente");
} else if (nota >= 14) {
  console.log("Bom");
} else if (nota >= 10) {
  console.log("Suficiente");
} else {
  console.log("Reprovado");
}

O JavaScript testa cada condição por ordem e para na primeira que for verdadeira — nunca chega a testar as seguintes. É por isso que a ordem importa: se tivesses posto nota >= 10 antes de nota >= 14, uma nota de 16 cairia no bloco errado, porque 16 também é maior ou igual a 10.

switch: uma alternativa quando compara sempre a mesma variável

Quando estás sempre a comparar a mesma variável contra vários valores exatos (não intervalos), o switch pode ser mais legível do que uma cadeia longa de else if:

javascript
const diaDaSemana = 3;
let nome;

switch (diaDaSemana) {
  case 1:
    nome = "Segunda-feira";
    break;
  case 2:
    nome = "Terça-feira";
    break;
  case 3:
    nome = "Quarta-feira";
    break;
  default:
    nome = "Dia inválido";
}

console.log(nome);

O break no fim de cada case é essencial: sem ele, a execução "cai" para o case seguinte mesmo que já tenha encontrado o valor certo (chama-se fall-through, e às vezes é usado de propósito, mas na maioria dos casos é um bug). O default funciona como o else final, para quando nenhum case corresponde.

Na prática, para a maioria dos problemas que vais resolver nesta plataforma, else if chega perfeitamente — usa switch quando tiveres uma lista longa (5+) de valores exatos a comparar.

3. O loop for: repetir um número conhecido de vezes

A estrutura de repetição mais usada quando já sabes quantas voltas queres dar.

O for é a tradução direta do ENQUANTO com contador que já escreveste em pseudocódigo na Fase 1, mas compacta as três partes (início, condição, incremento) numa só linha:

javascript
for (let i = 0; i < 5; i++) {
  console.log("Volta número", i);
}

As três partes dentro dos parênteses, separadas por ponto e vírgula:

  1. Inicialização (let i = 0) — corre uma única vez, antes da primeira volta.
  2. Condição (i < 5) — verificada antes de cada volta; se for falsa, o loop para.
  3. Incremento (i++) — corre no fim de cada volta, antes de a condição ser verificada de novo.

Porque começar em 0 (e não em 1)

Reparaste que o exemplo começa em i = 0? É uma convenção quase universal em programação — os índices de listas (que vais ver já na Fase 4) começam em 0, e é mais consistente manter o mesmo hábito em qualquer loop, mesmo quando ainda não estás a usar listas. Não é obrigatório, mas vais ver isto em praticamente todo o código que leres.

O erro que causa loops infinitos

Se esqueceres o incremento (i++), ou se a condição nunca se tornar falsa, o loop repete para sempre e o teu programa "bloqueia". Se isto te acontecer no terminal, Ctrl+C interrompe a execução à força. Antes de correr qualquer loop novo, faz o mesmo teste que fizeste na Fase 1: percorre-o mentalmente 2-3 voltas e confirma que a condição eventualmente se torna falsa.

for-loop.js
let total = 0;

for (let i = 1; i <= 10; i++) {
  total += i;
}

console.log("Soma de 1 a 10:", total); // 55
Somar os números de 1 a 10 com for — a versão em código do exercício de pseudocódigo da Fase 1

4. O loop while: repetir enquanto uma condição for verdadeira

Para quando não sabes de antemão quantas voltas vai levar.

O while repete um bloco de código enquanto a sua condição for verdadeira, mas — ao contrário do for — não tem uma estrutura fixa de inicialização/incremento embutida. Isso torna-o ideal quando não sabes de antemão quantas voltas o loop vai precisar:

javascript
let saldo = 100;
let mes = 0;

while (saldo > 0) {
  saldo -= 20;
  mes++;
}

console.log("Demorou", mes, "meses a esgotar o saldo.");

Aqui não sabemos à partida quantos meses vai demorar — depende do valor inicial do saldo. Um for obrigaria a fazer essa conta antes; um while simplesmente repete até a condição deixar de ser verdadeira.

do...while: garantir pelo menos uma execução

Existe uma variante, do...while, que executa o bloco primeiro e só depois verifica a condição — garante sempre pelo menos uma volta, mesmo que a condição já comece falsa:

javascript
let tentativas = 0;

do {
  tentativas++;
  console.log("Tentativa", tentativas);
} while (tentativas < 3);

Usa do...while quando o cenário exige "faz isto pelo menos uma vez, e repete se for preciso" — por exemplo, pedir uma password: tens sempre de pedir pelo menos uma vez, antes de saberes se está certa ou errada.

A responsabilidade é tua

Ao contrário do for, onde as três partes ficam todas juntas e visíveis, no while tu és responsável por garantir, dentro do bloco, que alguma coisa muda a condição eventualmente (como o saldo -= 20 no primeiro exemplo). Esquecer isso é a causa mais comum de loops infinitos em código real, não só em exercícios.

5. break e continue: controlar um loop por dentro

Sair de um loop antes do fim, ou saltar para a volta seguinte sem terminar a atual.

Duas palavras-chave dão-te controlo fino dentro de qualquer loop (for ou while):

  • break — sai imediatamente do loop, mesmo que a condição ainda fosse verdadeira. Já a viste no switch, mas funciona da mesma forma em loops.
  • continue — salta o resto do código desta volta e avança diretamente para a próxima verificação da condição.
javascript
for (let i = 1; i <= 10; i++) {
  if (i === 5) {
    break; // para completamente ao chegar a 5
  }
  console.log(i);
}
// Imprime: 1, 2, 3, 4

for (let i = 1; i <= 5; i++) {
  if (i % 2 === 0) {
    continue; // salta os números pares
  }
  console.log(i);
}
// Imprime: 1, 3, 5

Quando usar cada um

Usa break quando encontraste o que procuravas e não faz sentido continuar a procurar (ex: procurar um produto numa lista e parar assim que o encontrares). Usa continue quando queres ignorar certos casos mas continuar a processar os restantes (ex: processar uma lista de números mas ignorar os negativos).

Nenhum dos dois é obrigatório — a maioria dos loops simples não precisa deles — mas quando o problema pedir "para assim que encontrares X" ou "ignora os casos Y", são exatamente a ferramenta certa, e evitam-te ter de reescrever a condição do loop inteiro para lidar com esse caso especial.

Exercícios práticos

4 exercícios
Fácil

Exercício Fácil — Classificador de Faixa Etária

Usa uma cadeia de else if para classificar uma idade em bebé, criança, adolescente ou adulto.

FerramentasVS CodeTerminalNode.js

Objetivo: praticar decisões encadeadas com else if, prestando atenção à ordem das condições.

Passos a realizar

  1. Cria classificador-idade.js na pasta fase3.
  2. Declara const idade com um valor à tua escolha.
  3. Escreve uma cadeia if / else if / else que classifique: menor que 2 anos como "bebé", menor que 12 como "criança", menor que 18 como "adolescente", e o resto como "adulto".
  4. Imprime a classificação com console.log.
  5. Testa o teu código com pelo menos cinco valores diferentes de idade, incluindo os limites exatos (2, 12, 18), e confirma que cada um cai na categoria certa.

Dicas úteis

  • Testar os valores exatos dos limites (2, 12, 18) é a forma mais comum de apanhar um erro de "maior que" vs "maior ou igual a".
  • A ordem das condições importa — a mais restritiva (bebé) tem de vir primeiro, senão nunca é alcançada.

Erros comuns

  • Pôr a condição "menor que 18" antes de "menor que 12", fazendo com que crianças caiam sempre na categoria adolescente.
  • Esquecer o else final, deixando idades muito altas sem nenhuma categoria atribuída.

As minhas dúvidas

Fácil

Exercício Fácil — Gerador de Tabuada

Usa um loop for para imprimir a tabuada completa de um número.

FerramentasVS CodeTerminalNode.js

Objetivo: o teu primeiro for a fazer trabalho de verdade — gerar uma tabuada de multiplicação.

Passos a realizar

  1. Cria tabuada.js na pasta fase3.
  2. Declara const numero com o valor da tabuada que queres gerar (ex: 7).
  3. Usa um for que corra de 1 até 10.
  4. Dentro do loop, imprime uma linha no formato "numero x i = resultado" para cada volta.
  5. Muda o valor de numero e confirma que a tabuada inteira muda corretamente.

Fluxo de funcionamento

  1. 1i = 1
  2. 2i <= 10 ?
  3. 3Imprimir numero x i
  4. 4i++

Código de exemplo

tabuada.js
const numero = 7;

for (let i = 1; i <= 10; i++) {
  console.log(numero + " x " + i + " = " + (numero * i));
}
Estrutura de partida

Dicas úteis

  • Lembra-te: a condição do for é verificada antes de cada volta, incluindo a primeira — por isso i começa em 1 e a condição é i <= 10, não i < 10, se queres mesmo chegar a 10.

Erros comuns

  • Usar i < 10 quando queres incluir o 10, o que produz só até 9 vezes.
  • Esquecer o i++ no for, criando um loop infinito.

As minhas dúvidas

Médio

Exercício Médio — Simulador de Tentativas de Login

Combina while, if e um contador para simular um sistema de bloqueio após 3 tentativas erradas.

FerramentasVS CodeTerminalNode.js

Objetivo: combinar repetição e decisão para simular um cenário real de segurança — e praticar break dentro de um while.

Passos a realizar

  1. Cria login.js na pasta fase3.
  2. Cria uma lista simulada de tentativas de password erradas, por exemplo três strings dentro de um array (vais aprender arrays em detalhe na Fase 4, mas por agora usa apenas o índice [0], [1], [2] para os aceder).
  3. Declara const passwordCorreta com um valor fixo (ex: "1234").
  4. Usa um while com um contador de tentativas que começa em 0.
  5. Dentro do loop, compara a tentativa atual (usando o índice do array) com a passwordCorreta. Se coincidir, imprime "Acesso concedido" e usa break para sair do loop imediatamente.
  6. Se o contador chegar a 3 sem sucesso, imprime "Conta bloqueada" e o loop termina naturalmente (a condição do while deixa de ser verdadeira).
  7. Testa duas versões: uma onde a terceira tentativa simulada é a password certa, e outra onde nenhuma das três é.

Fluxo de funcionamento

  1. 1tentativas = 0
  2. 2tentativas < 3 ?
  3. 3Password certa? break
  4. 4tentativas++

Código de exemplo

login.js
const tentativasSimuladas = ["senha1", "1234", "abcd"];
const passwordCorreta = "1234";
let tentativas = 0;

while (tentativas < 3) {
  const tentativaAtual = tentativasSimuladas[tentativas];

  if (tentativaAtual === passwordCorreta) {
    console.log("Acesso concedido!");
    break;
  }

  console.log("Tentativa", tentativas + 1, "incorreta.");
  tentativas++;
}

if (tentativas === 3) {
  console.log("Conta bloqueada.");
}
Estrutura de partida

Dicas úteis

  • Testar os dois cenários (acerta à terceira / nunca acerta) é essencial — um código que só foi testado com o "caminho feliz" esconde bugs no caminho de falha.
  • O break aqui evita continuar a "gastar" tentativas depois de já teres tido sucesso — sem ele, o loop continuaria até ao fim mesmo com a password certa.

Erros comuns

  • Esquecer o break após o sucesso, fazendo o programa continuar a testar tentativas mesmo depois de a password já estar certa.
  • Comparar a tentativa errada (usar sempre o mesmo índice do array) em vez da tentativa correspondente ao número da volta atual.

As minhas dúvidas

Difícil

Exercício Difícil — FizzBuzz com Contadores

O clássico exercício de entrevista técnica: combina for, if/else encadeado, operador de resto e continue.

FerramentasVS CodeTerminalNode.js

O FizzBuzz é provavelmente o exercício de lógica mais usado em entrevistas de programação no mundo inteiro — e é uma síntese perfeita de tudo o que viste nesta fase.

Passos a realizar

  1. Cria fizzbuzz.js na pasta fase3.
  2. Usa um for que corra de 1 até 30.
  3. Para cada número: se for divisível por 3 e por 5 ao mesmo tempo, imprime "FizzBuzz". Se for divisível só por 3, imprime "Fizz". Se for divisível só por 5, imprime "Buzz". Caso contrário, imprime o próprio número.
  4. Usa o operador de resto da divisão (%) para testar divisibilidade — um número é divisível por outro se o resto da divisão for 0.
  5. Depois de teres a versão base a funcionar, adiciona um contador separado que conte quantas vezes "Fizz" apareceu sozinho (sem contar os "FizzBuzz"), e imprime esse total no fim, fora do loop.
  6. Usa continue para saltar a impressão do número nos casos em que já imprimiste Fizz, Buzz ou FizzBuzz (evita imprimir duas vezes por engano).

Fluxo de funcionamento

  1. 1i de 1 a 30
  2. 2Divisível por 3 e 5? FizzBuzz
  3. 3Só por 3? Fizz / Só por 5? Buzz
  4. 4Senão, imprime o número

Código de exemplo

fizzbuzz.js
let contadorFizz = 0;

for (let i = 1; i <= 30; i++) {
  if (i % 3 === 0 && i % 5 === 0) {
    console.log("FizzBuzz");
  } else if (i % 3 === 0) {
    console.log("Fizz");
    contadorFizz++;
  } else if (i % 5 === 0) {
    // completa aqui: imprime "Buzz"
  } else {
    console.log(i);
  }
}

console.log("Fizz sozinho apareceu", contadorFizz, "vezes.");
Ponto de partida — completa a lógica dos ramos em falta

Dicas úteis

  • A ordem importa: testa sempre "divisível por 3 e por 5" antes de testar cada um sozinho — senão o caso combinado nunca é alcançado (o mesmo erro do exercício da faixa etária).
  • Se o teu contador de "Fizz sozinho" não bater certo, confirma se estás a incrementá-lo só dentro do ramo certo do if/else e não do FizzBuzz.

Erros comuns

  • Usar dois if separados em vez de if / else if, fazendo com que um número como 15 imprima "Fizz" e depois "Buzz" em vez de "FizzBuzz".
  • Comparar com == 0 usando um número de divisão errado (dividir por 5 quando queria testar por 3, por exemplo) — um erro fácil de cometer a copiar e colar condições.

As minhas dúvidas