Capítulo 18: Funções com Retorno Tipado e Parâmetros (Modularização II)

🎯 Objetivo da Aula

Enquanto um Procedimento apenas executa uma tarefa sem devolver nada para quem o chamou (como imprimir um texto), uma Função é uma máquina matemática: ela recebe dados de entrada (parâmetros), processa a lógica internamente e devolve um resultado concreto (retorno) que pode ser guardado em uma variável ou utilizado dentro de uma expressão matemática.

Nesta aula, você aprenderá a:

  1. Compreender a diferença fundamental entre Procedimentos e Funções.
  2. Dominar a sintaxe: funcao Nome(params) : tipo_retorno ... retorne valor ... fimfuncao.
  3. Utilizar funções dentro de expressões de cálculo (total <- CalcularFrete(p, k) * 1.10).
  4. Compreender a diferença entre Passagem de Parâmetros por Valor e Passagem por Referência (var).

📥 Material de Apoio e Código-Fonte da Aula:


🏢 O Cenário Prático (Seu Desafio)

Situação: O departamento de engenharia tarifária da FastLog precisa padronizar os cálculos de frete de toda a empresa. A fórmula do frete é complexa: $$\text{FreteBase} = (\text{DistanciaKm} \times \text{R$,3.50}) + (\text{PesoKg} \times \text{R$,0.80})$$ $$\text{FreteFinal} = \text{FreteBase} + \text{Pedagios} + \text{Seguro}$$ Se cada programador escrever essa conta manualmente em diferentes partes do sistema, qualquer reajuste de tarifas causará divergências financeiras.

Missão: Você deve construir a Biblioteca Central de Funções Tarifárias, criando funções puras com retorno tipado que calculem o frete, o seguro e o ICMS de maneira centralizada.


🧠 Fundamentos: A Teoria das Funções na Computação

1. Procedimento vs Função (O Confronto Definitivo)

CaracterísticaProcedimento (procedimento)Função (funcao)
Gera valor de retorno?Não. Apenas executa ações na tela ou no sistema.Sim. Devolve obrigatoriamente um valor tipado.
Comando de SaídaNão possui.Exige o comando retorne valor.
Pode ser guardada em variável?❌ Não (x <- Imprimir() gera erro!).Sim (x <- CalcularTotal(10, 20)).
Pode ser usada dentro de um se?❌ Não.Sim (se ValidarSenha(s) entao).
graph LR
    subgraph Chamada ["Programa Principal"]
        Input["Argumentos: peso=500, km=200"] --> Func["Chama: CalcularFrete(500, 200)"]
    end
    subgraph CaixaPreta ["Função CalcularFrete() : real"]
        Func --> Proc["Processa cálculo interno"]
        Proc --> Ret["retorne 1100.00"]
    end
    Ret --> Output["Variável 'totalFrete' recebe: R$ 1100.00"]
    
    style Input fill:#2980b9,stroke:#fff,stroke-width:2px,color:#fff
    style Func fill:#8e44ad,stroke:#fff,stroke-width:2px,color:#fff
    style Ret fill:#27ae60,stroke:#fff,stroke-width:2px,color:#fff
    style Output fill:#217346,stroke:#fff,stroke-width:2px,color:#fff

2. A Sintaxe de uma Função no VisuAlg

1
2
3
4
5
6
7
8
funcao NomeDaFuncao(param1 : tipo1; param2 : tipo2) : tipo_do_retorno
var
   // Variáveis locais da função
   resultado : tipo_do_retorno
inicio
   resultado <- param1 + param2
   retorne resultado // Envia o valor de volta para quem chamou!
fimfuncao

3. Passagem de Parâmetros: Por Valor vs Por Referência (var)

  • Por Valor (Padrão): O computador envia apenas uma cópia do dado. Se a função alterar o valor do parâmetro lá dentro, a variável original de fora permanece intacta.
  • Por Referência (Palavra var no parâmetro): O computador envia o endereço real da memória. Qualquer modificação feita no parâmetro alterará diretamente a variável original fora da função!
1
2
3
4
5
// Exemplo por Referência:
procedimento ZerarSaldo(var saldo : real)
inicio
   saldo <- 0.0 // Altera a variável original fora do procedimento!
fimprocedimento

📖 Exemplo Guiado: Motor Tarifário com Funções Puras

Código do Algoritmo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
algoritmo "Motor_Tarifario_FastLog"
var
   peso, km, valorBase, valorComSeguro : real

// Declaração de Função 1: Cálculo de Frete Base
funcao CalcularFreteBase(distancia, pesoKg : real) : real
var
   custo : real
inicio
   custo <- (distancia * 3.50) + (pesoKg * 0.80)
   retorne custo
fimfuncao

// Declaração de Função 2: Aplicação de Taxa de Seguro (1.5%)
funcao AdicionarSeguro(valor : real) : real
inicio
   retorne valor * 1.015 // Acrescenta 1.5%
fimfuncao

// Procedimento 3: Ajuste do valor Por Referência (var)  altera a variável original do chamador
procedimento AplicarDescontoFidelidade(var valor : real; percentual : real)
inicio
   valor <- valor - (valor * percentual) // Modifica diretamente o parâmetro recebido por 'var'
fimprocedimento

inicio
   escreval("=== SIMULADOR DE CUSTO LOGÍSTICO ===")
   escreva("Distância da Rota (km): ")
   leia(km)
   escreva("Peso da Carga (kg): ")
   leia(peso)

   // Invocação das Funções encadeadas
   valorBase <- CalcularFreteBase(km, peso)
   valorComSeguro <- AdicionarSeguro(valorBase)

   escreval("")
   escreval("------------------------------------")
   escreval("Frete Base Calculado: R$ ", valorBase:8:2)
   escreval("Frete com Seguro RCTR-C: R$ ", valorComSeguro:8:2)

   // Passagem por Referência (var): a própria variável valorComSeguro é alterada dentro do procedimento
   AplicarDescontoFidelidade(valorComSeguro, 0.05) // Cliente fidelidade: 5% de desconto
   escreval("Frete Final (Desconto Fidelidade 5%): R$ ", valorComSeguro:8:2)
   escreval("------------------------------------")
fimalgoritmo

✅ Exemplo de Execução no Console (F9):

1
2
3
4
5
6
7
8
9
=== SIMULADOR DE CUSTO LOGÍSTICO ===
Distância da Rota (km): 400
Peso da Carga (kg): 1200

------------------------------------
Frete Base Calculado: R$  2360.00
Frete com Seguro RCTR-C: R$  2395.40
Frete Final (Desconto Fidelidade 5%): R$  2275.63
------------------------------------

Repare que AplicarDescontoFidelidade é um procedimento (não devolve valor com retorne), mas usa var no primeiro parâmetro: por isso ele consegue alterar diretamente o conteúdo de valorComSeguro sem precisar de uma atribuição de retorno como valorComSeguro <- AplicarDescontoFidelidade(...).


🛠️ Prática Obrigatória 1: Função de Validação Booleana de Placa

Passo 1: O Desafio

Crie uma função que receba uma string de placa e devolva um valor logico (VERDADEIRO se a placa for válida com exatamente 7 caracteres, ou FALSO se for inválida). Sintaxe: funcao ValidarTamanhoPlaca(placa : caractere) : logico (Dica: use a função nativa Compr(placa) = 7).

No programa principal, leia uma placa e use a sua função dentro de um se: se (ValidarTamanhoPlaca(p)) entao escreval("Placa regular") senao ...


🛠️ Prática Obrigatória 2: Calculadora de Média Ponderada de Performance

Crie uma função CalcularScoreMotorista(notaPontualidade, notaSeguranca, notaEconomia : real) : real que calcule a média ponderada com os seguintes pesos:

  • Pontualidade: Peso 4
  • Segurança: Peso 4
  • Economia de Combustível: Peso 2 $$\text{Score} = \frac{(P \times 4) + (S \times 4) + (E \times 2)}{10}$$

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_18_SeuNome_SeuSobrenome.alg.
  2. Certifique-se de que todas as funções utilizam o comando retorne para devolver o resultado.
  3. No Microsoft Teams, envie na tarefa “VisuAlg Cap 18 - Funções com Retorno”.
  4. Clique em Entregar (Turn In).

💡 Checkpoint de Lógica & Engenharia de Software

Você acabou de aplicar o conceito de Funções Puras (Pure Functions). Em programação funcional e arquiteturas modernas de microsserviços (como AWS Lambda e Google Cloud Functions), as funções são desenhadas sem efeitos colaterais: recebem dados por parâmetro e retornam novos dados com total previsibilidade.


🔥 Desafio de Fixação: Função de Conversão de Moeda (Dólar para Real)

Crie uma função ConverterDolar(valorUSD : real, cotacaoAtual : real) : real e utilize-a para cotar fretes internacionais cobrados em dólares.


🔑 Gabarito de Código Completo

Prática 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
algoritmo "Validador_Placa_Modular"
var
   placaDigitada : caractere

funcao ValidarTamanhoPlaca(placa : caractere) : logico
inicio
   se (Compr(placa) = 7) entao
      retorne VERDADEIRO
   senao
      retorne FALSO
   fimse
fimfuncao

inicio
   escreva("Digite a placa do caminhão (7 dígitos): ")
   leia(placaDigitada)

   escreval("")
   se (ValidarTamanhoPlaca(placaDigitada)) entao
      escreval(">>> [SUCESSO]: Placa '", placaDigitada, "' atende ao padrão Mercosul (7 caracteres).")
   senao
      escreval(">>> [ERRO]: Placa inválida! Comprimento incorreto.")
   fimse
fimalgoritmo

Prática 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
algoritmo "Score_Motorista"
var
   n1, n2, n3, scoreFinal : real

funcao CalcularScoreMotorista(pont, seg, econ : real) : real
var
   mediaPonderada : real
inicio
   mediaPonderada <- ((pont * 4.0) + (seg * 4.0) + (econ * 2.0)) / 10.0
   retorne mediaPonderada
fimfuncao

inicio
   escreval("=== AVALIAÇÃO TRIMESTRAL DE MOTORISTAS ===")
   escreva("Nota de Pontualidade (0 a 10): ") leia(n1)
   escreva("Nota de Segurança Viária (0 a 10): ") leia(n2)
   escreva("Nota de Economia Diesel (0 a 10): ") leia(n3)

   scoreFinal <- CalcularScoreMotorista(n1, n2, n3)

   escreval("")
   escreval("------------------------------------------")
   escreval("ÍNDICE DE PERFORMANCE (SCORE): ", scoreFinal:5:2)
   
   se (scoreFinal >= 8.5) entao
      escreval("STATUS: CLASSIFICAÇÃO EXCELENTE (Elegível a Prêmio)")
   senao
      escreval("STATUS: CLASSIFICAÇÃO REGULAR")
   fimse
   escreval("------------------------------------------")
fimalgoritmo

Desafio:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
algoritmo "Conversor_Moedas"
var
   freteUSD, cotacao, freteBRL : real

funcao ConverterDolar(valorUSD, cotacao : real) : real
inicio
   retorne valorUSD * cotacao
fimfuncao

inicio
   escreval("=== COTAÇÃO DE FRETE INTERNACIONAL ===")
   escreva("Valor do Frete Marítimo (US$): ") leia(freteUSD)
   escreva("Cotação Atual do Dólar (R$): ") leia(cotacao)

   freteBRL <- ConverterDolar(freteUSD, cotacao)

   escreval("")
   escreval("Valor Original em Dólares : US$ ", freteUSD:9:2)
   escreval("VALOR CONVERTIDO EM REAIS : R$  ", freteBRL:9:2)
fimalgoritmo

📝 Atividade Extra: Questionário de Fixação (Caderno)

Instruções: Responda no caderno, de próprio punho, as 10 perguntas abaixo com base no que foi estudado neste capítulo. Ao concluir, leve o caderno até o professor para correção e visto.

  1. Segundo a tabela comparativa dos Fundamentos, um Procedimento gera valor de retorno? E uma Função gera valor de retorno?
  2. Qual comando é obrigatório dentro de uma função para devolver o valor de retorno a quem a chamou?
  3. É possível guardar o retorno de um procedimento em uma variável (como em x <- Imprimir())? E o retorno de uma função?
  4. Escreva a estrutura geral da sintaxe de uma função no VisuAlg, indicando onde o tipo do valor de retorno é declarado no cabeçalho.
  5. Qual é a diferença entre a passagem de parâmetros por valor e a passagem por referência (uso da palavra var no parâmetro)?
  6. No Cenário Prático, quais são as duas fórmulas (FreteBase e FreteFinal) usadas para calcular o custo do frete da FastLog?
  7. No Exemplo Guiado (Motor_Tarifario_FastLog), quais são as duas funções criadas, e o que cada uma calcula?
  8. Na Prática Obrigatória 1, qual função nativa do VisuAlg é sugerida para verificar o comprimento da placa, e quantos caracteres uma placa válida deve ter?
  9. Na Prática Obrigatória 2, quais são os pesos atribuídos a Pontualidade, Segurança e Economia de Combustível no cálculo do Score do motorista?
  10. Segundo o Checkpoint de Lógica, a que conceito de programação as funções sem efeitos colaterais estão associadas, e quais dois serviços de nuvem são citados como exemplo?