MB Academy

Controle de Fluxo

Aprenda a controlar o fluxo de execução do seu código com condições, operadores lógicos e estruturas como if/else e switch.

Até aqui, aprendemos como armazenar informações com tipos definidos. Agora, vamos ver como o programa pode "tomar decisões" e controlar seu fluxo de execução com base em condições. O controle de fluxo permite que seu código reaja a diferentes situações de forma dinâmica.

O que é Controle de Fluxo?

O controle de fluxo é um conjunto de instruções que permite alterar o comportamento do programa dependendo de condições específicas ou de ações repetitivas. Em vez de executar o código de forma linear, como uma lista de passos sem variações, o controle de fluxo possibilita:

  • Executar ou ignorar blocos de código com base em condições.
  • Repetir instruções enquanto uma determinada condição for verdadeira.

Por exemplo, com o controle de fluxo, você pode dizer ao programa:

"Se o usuário tiver 18 anos ou mais, permita o acesso ao conteúdo; caso contrário, exiba uma mensagem de bloqueio."

Vamos começar aprendendo como criar condições simples e utilizá-las em diferentes estruturas.

1. Condições

As condições são a base de qualquer sistema de controle de fluxo. Elas permitem que o programa execute diferentes blocos de código dependendo de uma situação ou valor. Uma condição sempre avalia para um dos dois resultados: verdadeiro (true) ou falso (false).

A ideia é simples: você define uma expressão lógica, o programa avalia essa expressão e, com base no resultado, decide qual ação realizar.

Exemplos do mundo real

Vamos pensar em situações do dia a dia que podem ser modeladas como condições:

  • Se estiver chovendo, leve um guarda-chuva. Caso contrário, use óculos de sol.
  • Se o saldo na conta for suficiente, aprove a compra. Caso contrário, exiba uma mensagem de erro.
  • Se a temperatura for maior que 30°C, ligue o ar-condicionado.

Essas situações podem ser traduzidas para código de forma direta, usando condições e estruturas de controle.

Criando uma Condição

No contexto da programação, uma condição geralmente envolve a comparação de valores usando operadores relacionais. Esses operadores são utilizados para comparar dois valores e retornar um resultado booleano (true ou false).

Operadores relacionais

OperadorDescriçãoExemploResultado
>Maior que5 > 3true
<Menor que5 < 3false
>=Maior ou igual a5 >= 5true
<=Menor ou igual a4 <= 3false
===Igualdade estrita (valor e tipo)"5" === 5false
!==Diferença estrita (valor e tipo)"5" !== 5true

Exemplo básico de condição:

let idade = 18;

if (idade >= 18) {
  console.log("Você é maior de idade.");
} else {
  console.log("Você é menor de idade.");
}
// Saída: "Você é maior de idade."

Importância das Condições

Códigos que usam condições tornam os programas interativos e dinâmicos. Por exemplo:

  1. Validação de dados: Verificar se um usuário preencheu todos os campos de um formulário.
  2. Decisões baseadas em valores: Alterar o layout de uma página dependendo do tema selecionado pelo usuário.
  3. Controle em jogos: Determinar se o jogador venceu, perdeu ou ainda está no jogo.

Condições Simples

Códigos com condições simples verificam apenas uma expressão e tomam uma ação com base nela.

Exemplo prático:

let saldo = 150;

if (saldo > 100) {
  console.log("Você tem saldo suficiente.");
}
// Saída: "Você tem saldo suficiente."

No exemplo acima:

  • O código verifica se o saldo é maior que 100.
  • Se for verdadeiro (true), ele executa o que está dentro do bloco {}.

Condições Compostas

Podemos combinar várias condições em uma única expressão usando operadores lógicos (detalhados mais à frente). Isso permite criar lógica mais complexa.

Exemplo prático:

let saldo = 150;
let compra = 120;

if (saldo > compra && compra > 0) {
  console.log("Compra aprovada.");
} else {
  console.log("Compra recusada.");
}
// Saída: "Compra aprovada."

Aqui:

  1. O programa verifica duas condições:
    • O saldo é maior que o valor da compra.
    • O valor da compra é maior que zero.
  2. Ambas as condições precisam ser verdadeiras para que a mensagem "Compra aprovada." seja exibida.

2. Estruturas Condicionais

As estruturas condicionais são ferramentas que permitem implementar as condições de maneira organizada no código. Elas são usadas para definir diferentes caminhos de execução com base no resultado de uma expressão lógica. As principais estruturas condicionais no TypeScript são:

  1. if e else
  2. else if
  3. switch-case
  4. Operador ternário

Vamos explorar cada uma delas detalhadamente, com exemplos práticos e explicações.

if e else

O bloco if é a estrutura condicional mais básica. Ele avalia uma expressão e executa o código dentro de suas chaves ({}) apenas se o resultado da expressão for verdadeiro (true).

Já o bloco else é usado para especificar o que deve acontecer quando a condição no if não for atendida (ou seja, quando o resultado for falso).

Sintaxe

if (condição) {
  // Código a ser executado se a condição for verdadeira
} else {
  // Código a ser executado se a condição for falsa
}

Exemplo

Imagine que queremos verificar se uma pessoa é maior de idade:

let idade = 17;

if (idade >= 18) {
  console.log("Você é maior de idade.");
} else {
  console.log("Você é menor de idade.");
}
// Saída: "Você é menor de idade."

Nesse caso:

  • Se idade for maior ou igual a 18, o programa exibirá "Você é maior de idade".
  • Caso contrário, exibirá "Você é menor de idade".

Dicas importantes

  • Sempre use chaves ({}), mesmo quando o bloco de código tiver apenas uma linha. Isso torna o código mais seguro e fácil de expandir no futuro.
  • Certifique-se de que a condição seja uma expressão que retorne um valor booleano (ou algo que o TypeScript possa converter para true ou false).

else if

Quando precisamos verificar mais de uma condição, podemos usar a estrutura else if. Ela permite adicionar testes intermediários antes de chegar ao bloco else.

Sintaxe

if (condição1) {
  // Código para condição1
} else if (condição2) {
  // Código para condição2
} else {
  // Código para todas as outras situações
}

Exemplo

Vamos verificar se a temperatura de uma sala está baixa, ideal ou alta:

let temperatura = 28;

if (temperatura < 18) {
  console.log("Está frio.");
} else if (temperatura >= 18 && temperatura <= 25) {
  console.log("A temperatura está agradável.");
} else {
  console.log("Está quente.");
}
// Saída: "Está quente."

Aqui:

  • O programa verifica se a temperatura é menor que 18 (frio).
  • Se a primeira condição não for verdadeira, verifica se está entre 18 e 25 (agradável).
  • Caso nenhuma dessas condições seja atendida, considera que está quente.

switch-case

A estrutura switch-case é ideal para situações em que você precisa comparar uma variável com vários valores possíveis. Ela é frequentemente usada quando há muitas condições que dependem de um único valor.

Sintaxe

switch (variavel) {
  case valor1:
    // Código para valor1
    break;
  case valor2:
    // Código para valor2
    break;
  default:
    // Código para todos os outros casos
    break;
}

Exemplo

Vamos verificar o dia da semana com base em um número:

let dia = 3;
let nomeDoDia: string;

switch (dia) {
  case 1:
    nomeDoDia = "Segunda-feira";
    break;
  case 2:
    nomeDoDia = "Terça-feira";
    break;
  case 3:
    nomeDoDia = "Quarta-feira";
    break;
  // ... outros casos
  default:
    nomeDoDia = "Dia inválido";
    break;
}

console.log(nomeDoDia); // Saída: Quarta-feira

O comando break é essencial para impedir que o código continue executando os casos abaixo do que foi correspondido.

Operador Ternário

É uma forma compacta de escrever um if-else simples, geralmente para atribuir um valor a uma variável.

Sintaxe: condição ? valor_se_true : valor_se_false;

let numero = 7;
let resultado: string = numero % 2 === 0 ? "Par" : "Ímpar";

console.log(resultado); // Saída: Ímpar

Aqui:

  • A condição (numero % 2 === 0) verifica se o número é divisível por 2.
  • Se for verdadeiro, a variável resultado recebe o valor "Par".
  • Caso contrário, recebe o valor "Ímpar".

O operador ternário é excelente para atribuições diretas e retornos rápidos, mas não deve substituir if-else quando há mais de uma ação sendo executada. Priorize legibilidade.

Comparando as Estruturas

EstruturaQuando usar
if-elsePara condições simples ou que envolvam múltiplas expressões lógicas.
else ifQuando há mais de duas condições possíveis que precisam ser verificadas.
switch-caseQuando há muitas comparações baseadas no mesmo valor.
Operador ternárioPara condições simples que não comprometem a legibilidade do código.

Boas Práticas no Uso de Estruturas Condicionais

  1. Evite aninhar estruturas desnecessariamente: Condições muito profundas podem tornar o código confuso.
  2. Considere a legibilidade: Use o operador ternário apenas para condições muito simples.
  3. Use switch-case com parcimônia: Essa estrutura pode ser menos flexível do que um if-else em casos mais complexos.
  4. Sempre cubra os casos inesperados: Inclua um else ou default para garantir que seu programa lide com entradas imprevistas.

3. Operadores Lógicos

Os operadores lógicos são ferramentas poderosas em programação que permitem combinar ou modificar condições, como já vimos antes. Eles são fundamentais para criar expressões lógicas mais complexas, ampliando o controle sobre o fluxo do programa. Em TypeScript, temos três operadores lógicos principais:

  1. AND (&&)
  2. OR (||)
  3. NOT (!)

Cada um deles desempenha um papel específico e pode ser usado em conjunto para atender a diferentes necessidades. Vamos detalhar cada operador com exemplos claros.

Operador AND (&&)

O operador AND é usado para combinar duas ou mais condições e retorna true apenas se todas as condições forem verdadeiras.

Sintaxe

condição1 && condição2;

Exemplo

Imagine que queremos verificar se uma pessoa está apta para votar (ser maior de 18 anos e ser cidadã registrada):

let idade = 20;
let cidadania = true;

if (idade >= 18 && cidadania) {
  console.log("Você está apto para votar.");
} else {
  console.log("Você não está apto para votar.");
}
// Saída: "Você está apto para votar."

Funcionamento

  • Se idade >= 18 e cidadania forem verdadeiras, o resultado será true.
  • Caso qualquer uma das condições seja falsa, o resultado será false.

Tabela Verdade do &&

Condição 1Condição 2Resultado
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

Esta tabela ilustra claramente que o operador AND só retorna true quando ambas as condições são verdadeiras. Isso é fundamental para entender como construir expressões lógicas mais complexas em seus programas.

Operador OR (||)

O operador OR retorna true se pelo menos uma das condições for verdadeira. Ele é útil quando apenas uma das condições precisa ser atendida.

Sintaxe

condição1 || condição2;

Exemplo

Vamos verificar se uma pessoa pode acessar um desconto em um evento. O desconto é aplicado para menores de 18 anos ou estudantes:

let idade = 20;
let estudante = true;

if (idade < 18 || estudante) {
  console.log("Você tem direito a desconto.");
} else {
  console.log("Você não tem direito a desconto.");
}
// Saída: "Você tem direito a desconto."

Funcionamento

  • Se idade < 18 for false, o operador ainda verificará estudante. Como estudante é true, o resultado geral será true.

Tabela Verdade do ||

Condição 1Condição 2Resultado
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

Operador NOT (!)

O operador NOT inverte o valor lógico de uma expressão. Ele transforma true em false e vice-versa.

Sintaxe

!condição;

Exemplo

Vamos verificar se uma pessoa não é maior de idade:

let idade = 16;

if (!(idade >= 18)) {
  console.log("Você não é maior de idade.");
} else {
  console.log("Você é maior de idade.");
}
// Saída: "Você não é maior de idade."

Funcionamento

  • A expressão idade >= 18 é avaliada como false porque 16 não é maior ou igual a 18.
  • O operador NOT (!) inverte o resultado, transformando false em true.

Combinações de Operadores Lógicos

Os operadores lógicos podem ser combinados para criar condições mais elaboradas. Quando combinamos vários operadores, é importante entender a precedência e usar parênteses para controlar a ordem das operações.

Exemplo 1: Verificando múltiplas condições

Imagine que queremos liberar acesso a uma área apenas para maiores de idade e estudantes, mas que também permitimos o acesso a menores de idade ou professores:

let idade = 17;
let estudante = true;
let professor = false;

if ((idade >= 18 && estudante) || idade < 18 || professor) {
  console.log("Acesso permitido.");
} else {
  console.log("Acesso negado.");
}
// Saída: "Acesso permitido."

Exemplo 2: Usando ! para negar uma condição

Queremos restringir o acesso apenas para quem não é professor:

let professor = false;

if (!professor) {
  console.log("Acesso permitido.");
} else {
  console.log("Acesso negado.");
}
// Saída: "Acesso permitido."

Precedência dos Operadores Lógicos

Quando combinamos operadores, o TypeScript segue uma ordem de precedência para avaliar as expressões. A ordem é a seguinte:

  1. NOT (!) – Avaliado primeiro.
  2. AND (&&) – Avaliado depois.
  3. OR (||) – Avaliado por último.

Exemplo

let a = true;
let b = false;
let c = true;

console.log(!a || (b && c));
// Saída: false

Explicação:

  1. O operador NOT (!a) transforma a em false.
  2. Depois, o operador AND (b && c) é avaliado. Como b é false, o resultado do AND será false.
  3. Por fim, o operador OR (false || false) retorna false.

Boas Práticas no Uso de Operadores Lógicos

  1. Use parênteses para deixar as condições claras: Mesmo que você conheça a precedência, parênteses tornam o código mais legível para outras pessoas.

    if ((idade >= 18 && estudante) || professor) {
      // Mais claro e fácil de entender
    }
  2. Evite expressões muito longas: Quebrar condições em variáveis auxiliares melhora a legibilidade.

    let maiorDeIdade = idade >= 18;
    let temDesconto: boolean = estudante || professor;
    
    if (maiorDeIdade && temDesconto) {
      console.log("Acesso permitido.");
    }
  3. Teste todas as possibilidades: Ao combinar operadores, certifique-se de que todas as combinações de entradas possíveis foram testadas.

Para praticar

Vamos testar seus conhecimentos sobre controle de fluxo com um exercício.

Cenário: Crie um script que avalie a nota de um aluno.

Requisitos:

  1. Crie uma variável nota do tipo number e atribua a ela um valor (de 0 a 10).
  2. Use a estrutura if-else if-else para verificar a situação do aluno:
    • Se a nota for maior ou igual a 7, exiba: "Aprovado".
    • Se a nota for maior ou igual a 5 e menor que 7, exiba: "Recuperação".
    • Se a nota for menor que 5, exiba: "Reprovado".
  3. Teste com diferentes valores para a variável nota.
Clique para ver uma possível solução
let nota = 8.5;

if (nota >= 7) {
  console.log("Aprovado");
} else if (nota >= 5) {
  console.log("Recuperação");
} else {
  console.log("Reprovado");
}

Note que no else if não precisamos verificar se a nota é < 7, pois essa condição só será testada se a primeira (nota >= 7) já for falsa.

Conclusão

Com o controle de fluxo, seu código passa a pensar e se adaptar. Ele pode reagir a diferentes valores e executar blocos de código de acordo com regras. Esse é um dos pilares da programação: a capacidade de tomar decisões.

No próximo passo, vamos aprender como repetir ações de forma controlada, usando as estruturas de repetição como for e while.