Pular para o conteúdo

Estruturas de Decisão

Quando escrevemos um programa, nem sempre queremos que ele faça exatamente a mesma coisa em todas as situações. Em muitos problemas, o programa precisa analisar uma condição e, a partir disso, decidir qual caminho seguir.

É exatamente para isso que servem as estruturas de decisão. Com elas, o programa consegue tomar decisões com base em um resultado lógico: verdadeiro ou falso.

Mesmo fora da programação, nós tomamos decisões o tempo todo seguindo regras bem parecidas com as de um algoritmo.

Pense em algumas situações:

  • Se o seu personagem estiver com pouca vida, faz sentido usar uma poção.
  • Se ainda não deu o horário da aula, você continua esperando.
  • Se você tiver saldo suficiente, consegue comprar um item no jogo.
  • Se estiver chovendo, talvez seja melhor levar um guarda-chuva.

Em todos esses casos, existe uma pergunta por trás da decisão:

A condição é verdadeira ou falsa?

Se a resposta for verdadeira, uma ação acontece. Se for falsa, outra ação pode acontecer.

Essa é a ideia central do se. Ele avalia uma condição e, com base no resultado, escolhe um caminho para o programa seguir.

No tópico anterior, vimos que operadores de comparação e operadores lógicos produzem um resultado verdadeiro ou falso.

Agora, vamos usar esse resultado para controlar o fluxo do programa.

Isso significa que o se pode receber:

  • uma expressão lógica, como idade >= 18
  • uma variável lógica, como pode_entrar

Veja os dois casos:

programa
{
funcao inicio()
{
inteiro moedas
moedas = 15
se (moedas >= 10) {
escreva("Você pode comprar o item.\n")
}
}
}
programa
{
funcao inicio()
{
logico portal_aberto
portal_aberto = verdadeiro
se (portal_aberto) {
escreva("O personagem pode atravessar o portal.\n")
}
}
}

Nos dois exemplos, o se avalia algo que termina em verdadeiro ou falso. A diferença é que, no primeiro caso, usamos uma comparação diretamente. No segundo, usamos uma variável do tipo logico.

A forma básica do se no Portugol é esta:

se (condicao) {
// bloco executado se a condição for verdadeira
}

Vamos analisar cada parte:

  • se indica que o programa vai tomar uma decisão.
  • (condicao) é a expressão que será avaliada.
  • { } delimitam o bloco de código que será executado se a condição for verdadeira.

Veja um exemplo completo:

programa
{
funcao inicio()
{
inteiro energia
escreva("Digite a energia do jogador: ")
leia(energia)
se (energia >= 50) {
escreva("Você pode usar o golpe especial.\n")
}
escreva("Fim do turno.")
}
}

Se o valor de energia >= 50 for verdadeiro, a mensagem sobre o golpe especial será exibida. Se for falso, essa mensagem não aparece.

Já a mensagem Fim do turno. aparece de qualquer jeito, porque ela está fora do bloco do se.

flowchart TD
    A((Início)) --> B[/LEIA energia/]
    B --> C{energia >= 50?}
    C -- Sim --> D[/IMPRIME "Você pode usar o golpe especial."/]
    C -- Não --> E[/IMPRIME "Fim do turno."/]
    D --> E
    E --> F((Fim))

Um bloco de código é o conjunto de instruções que fica entre chaves.

Observe este exemplo:

programa
{
funcao inicio()
{
inteiro moedas
moedas = 12
se (moedas >= 10) {
escreva("Compra liberada.\n")
escreva("Você tem moedas suficientes.\n")
}
escreva("Programa encerrado.")
}
}

As duas mensagens dentro das chaves pertencem ao bloco do se. Por isso, elas só serão executadas se a condição for verdadeira.

A mensagem Programa encerrado. está fora das chaves. Isso significa que ela não faz parte do bloco do se e será executada independentemente do resultado da condição.

As chaves ajudam a deixar claro onde um bloco começa e onde ele termina. Quando o programa entra em um bloco, ele executa as instruções que estão ali dentro.

Às vezes, não basta dizer o que acontece quando a condição é verdadeira. Também queremos definir o que acontece quando ela for falsa.

Nesses casos, usamos senao.

se (condicao) {
// bloco executado se a condição for verdadeira
} senao {
// bloco executado se a condição for falsa
}

Veja um exemplo:

programa
{
funcao inicio()
{
inteiro durabilidade
escreva("Digite a durabilidade da picareta: ")
leia(durabilidade)
se (durabilidade > 0) {
escreva("A picareta ainda pode ser usada.")
} senao {
escreva("A picareta quebrou.")
}
}
}

Aqui acontece o seguinte:

  • se durabilidade > 0 for verdadeiro, o primeiro bloco será executado
  • senao, o segundo bloco será executado

Perceba um ponto importante: o programa não executa os dois blocos. Ele escolhe apenas um deles com base no resultado da condição.

flowchart TD
    A((Início)) --> B[/LEIA durabilidade/]
    B --> C{durabilidade > 0?}
    C -- Sim --> D[/IMPRIME "A picareta ainda pode ser usada."/]
    C -- Não --> E[/IMPRIME "A picareta quebrou."/]
    D --> F((Fim))
    E --> F

Esse fluxograma mostra exatamente a ideia de decisão: dependendo da resposta para uma pergunta, seguimos por um caminho diferente.

Esse é o ponto mais importante de se e senao.

O programa:

  1. avalia a condição
  2. obtém um resultado lógico: verdadeiro ou falso
  3. escolhe qual bloco deve ser executado

Se o resultado for verdadeiro, o programa entra no bloco do se.

Se o resultado for falso, o programa entra no bloco do senao.

Por isso, as chaves são tão importantes: elas mostram exatamente qual conjunto de instruções pertence a cada caminho.

Vamos juntar tudo em um exemplo simples:

programa
{
funcao inicio()
{
logico tem_convite
tem_convite = falso
se (tem_convite) {
escreva("Você pode entrar na festa.\n")
escreva("Aproveite o evento!\n")
} senao {
escreva("Você não pode entrar na festa.\n")
escreva("É preciso ter convite.\n")
}
escreva("Verificação encerrada.")
}
}

Nesse exemplo, cada bloco possui duas instruções. Como tem_convite vale falso, o programa executa apenas o bloco do senao.

Depois disso, ele continua a execução normalmente e mostra Verificação encerrada., porque essa instrução está fora dos blocos da decisão.