Por que decompor em rotinas reutilizáveis
Ao resolver um problema maior, é comum existirem partes que se repetem (validar um dado, converter um formato, calcular um valor). Em pseudocódigo essencial, essas partes devem virar rotinas nomeadas para: reduzir repetição, tornar o algoritmo principal mais legível, facilitar testes e diminuir erros ao centralizar regras em um único lugar.
Neste capítulo, vamos padronizar dois tipos de rotinas:
- FUNÇÃO: retorna um valor (ex.: número, texto, lógico, registro).
- PROCEDIMENTO: não retorna valor; executa uma ação (ex.: preencher campos de saída, atualizar uma estrutura, registrar um evento).
Padrão de assinatura: nome, parâmetros e tipos
Assinatura de FUNÇÃO (com retorno)
Uma função deve declarar explicitamente: nome, lista de parâmetros com direção (ENTRADA/SAÍDA/REFERÊNCIA), tipos e tipo de retorno.
FUNÇÃO NomeDaFuncao(ENTRADA p1: Tipo1, ENTRADA p2: Tipo2, SAÍDA p3: Tipo3): TipoRetornoRegras práticas:
- Use verbos que indiquem resultado:
CalcularTotal,ConverterParaCelsius,EhValido. - Retorno deve ser único e claro. Se precisar devolver vários valores, prefira retornar um registro ou usar parâmetros de saída (mas evite misturar retorno e muitas saídas).
- Parâmetros devem ter nomes que indiquem papel:
texto,idade,taxa,listaItens.
Assinatura de PROCEDIMENTO (sem retorno)
Um procedimento declara nome e parâmetros; não possui tipo de retorno.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
PROCEDIMENTO NomeDoProcedimento(ENTRADA p1: Tipo1, SAÍDA p2: Tipo2, REFERÊNCIA p3: Tipo3)Regras práticas:
- Use verbos de ação:
PreencherResumo,OrdenarLista,AtualizarEstoque. - Se o procedimento só calcula algo, considere transformá-lo em função (mais previsível e testável).
Direção de parâmetros: ENTRADA, SAÍDA e REFERÊNCIA
Para evitar ambiguidades e efeitos colaterais, declare a direção de cada parâmetro:
- ENTRADA: a rotina apenas lê o valor. Não deve alterar o parâmetro.
- SAÍDA: a rotina preenche/define o valor. O chamador fornece uma variável para receber o resultado.
- REFERÊNCIA: a rotina pode ler e alterar o valor original do chamador. Use com cuidado e apenas quando necessário.
Quando usar cada um
| Situação | Preferência | Exemplo |
|---|---|---|
| Calcular e devolver um único valor | FUNÇÃO com retorno | CalcularDesconto(preco, taxa): Real |
| Precisa devolver vários valores relacionados | Retornar registro OU usar SAÍDA | CalcularMinMax(lista): Registro |
| Modificar uma estrutura existente (ex.: vetor) por eficiência | PROCEDIMENTO com REFERÊNCIA | Ordenar(REFERÊNCIA v) |
| Inicializar/gerar dados em variáveis do chamador | PROCEDIMENTO com SAÍDA | LerIntervalo(SAÍDA ini, SAÍDA fim) |
Contrato da rotina: pré-condições e pós-condições
Para documentar o que a rotina espera e garante, escreva um contrato breve com:
- Pré-condições: o que deve ser verdadeiro antes de chamar.
- Pós-condições: o que será verdadeiro após executar, incluindo o retorno e alterações em SAÍDA/REFERÊNCIA.
Formato recomendado (logo acima da assinatura):
// PRÉ: condições sobre entradas (faixas, formatos, não nulo, tamanho mínimo etc.); se violadas, definir comportamento (erro, retorno padrão, sinalização) // PÓS: descreve retorno e quais parâmetros podem ser modificadosExemplo de contrato bem definido
// PRÉ: texto contém apenas dígitos e opcionalmente um sinal '-' no início; texto não é vazio // PÓS: retorna o inteiro representado por texto; não altera parâmetros de entrada FUNÇÃO ConverterParaInteiro(ENTRADA texto: Texto): InteiroRegras para evitar efeitos colaterais inesperados
Efeitos colaterais são mudanças fora do retorno esperado (alterar variáveis globais, modificar parâmetros de entrada, mudar estruturas sem avisar). Para manter previsibilidade:
- Preferir funções puras: funções devem depender apenas das entradas e retornar um valor, sem escrever em tela, sem ler entrada, sem alterar estado global.
- ENTRADA é somente leitura: nunca modifique parâmetros marcados como ENTRADA.
- REFERÊNCIA só quando necessário: se usar, declare claramente na assinatura e na pós-condição o que pode mudar.
- Evite globais: passe dados por parâmetros. Se algo for compartilhado, documente explicitamente no contrato.
- Uma responsabilidade por rotina: se a rotina valida e também converte e também calcula, ela tende a ficar difícil de reutilizar. Separe em rotinas menores.
- Nomear para indicar efeito:
NormalizarTextosugere alteração;TextoNormalizadosugere retorno sem modificar entrada.
Passo a passo: decompondo um problema em rotinas
Use este roteiro para transformar um algoritmo grande em rotinas reutilizáveis:
Liste as etapas do problema em frases curtas (ex.: validar dados, converter unidades, calcular total, formatar saída).
Marque o que se repete ou o que é uma regra de negócio isolada (ex.: validação de faixa, cálculo de imposto).
Escolha FUNÇÃO vs PROCEDIMENTO: se produz um valor, FUNÇÃO; se altera/produz múltiplas saídas ou modifica estrutura, PROCEDIMENTO.
Defina assinatura: parâmetros mínimos necessários, direção (ENTRADA/SAÍDA/REFERÊNCIA) e tipos.
Escreva contrato: pré e pós-condições, incluindo comportamento em caso de entrada inválida.
Implemente e teste mentalmente com 2 ou 3 casos (normal, limite, inválido).
Integre no algoritmo principal mantendo o fluxo principal curto e legível.
Exemplos práticos de funções pequenas
1) Função de validação (retorna Lógico)
// PRÉ: minimo <= maximo // PÓS: retorna VERDADEIRO se valor está no intervalo [minimo, maximo] FUNÇÃO EstaNoIntervalo(ENTRADA valor: Real, ENTRADA minimo: Real, ENTRADA maximo: Real): Logico SE valor < minimo ENTÃO RETORNE FALSO SENÃO SE valor > maximo ENTÃO RETORNE FALSO SENÃO RETORNE VERDADEIRO FIM SE FIM FUNÇÃOUso típico: validar idade, nota, temperatura, quantidade.
2) Função de conversão (transforma formato)
// PRÉ: celsius é um número válido // PÓS: retorna a conversão para Fahrenheit FUNÇÃO ConverterCelsiusParaFahrenheit(ENTRADA celsius: Real): Real RETORNE (celsius * 9 / 5) + 32 FIM FUNÇÃORegra prática: conversões devem ser funções (sem imprimir, sem ler, sem alterar variáveis externas).
3) Função de cálculo (regra de negócio)
// PRÉ: preco >= 0; taxaDesconto entre 0 e 1 // PÓS: retorna preco com desconto aplicado FUNÇÃO CalcularPrecoComDesconto(ENTRADA preco: Real, ENTRADA taxaDesconto: Real): Real RETORNE preco * (1 - taxaDesconto) FIM FUNÇÃOExemplos práticos de procedimentos
1) Procedimento com SAÍDA (produz múltiplos resultados)
// PRÉ: a e b são números válidos // PÓS: menor recebe o menor valor; maior recebe o maior valor PROCEDIMENTO CalcularMenorMaior(ENTRADA a: Real, ENTRADA b: Real, SAÍDA menor: Real, SAÍDA maior: Real) SE a <= b ENTÃO menor <- a maior <- b SENÃO menor <- b maior <- a FIM SE FIM PROCEDIMENTO2) Procedimento com REFERÊNCIA (modifica estrutura)
// PRÉ: v possui tamanho >= 1 // PÓS: v é reorganizado em ordem crescente (modificação in-place) PROCEDIMENTO OrdenarCrescente(REFERÊNCIA v: Vetor de Inteiro) // implementação omitida; o ponto é o contrato e o uso de REFERÊNCIA FIM PROCEDIMENTORegra prática: quando houver REFERÊNCIA, deixe explícito no contrato o que muda (ordem, conteúdo, campos).
Integração: algoritmo principal usando rotinas
Exemplo de integração com validação, conversão e cálculo. O objetivo é manter o algoritmo principal como uma sequência de chamadas legíveis, delegando detalhes às rotinas.
// Rotinas auxiliares (assinaturas e contratos já definidos acima) FUNÇÃO EstaNoIntervalo(ENTRADA valor: Real, ENTRADA minimo: Real, ENTRADA maximo: Real): Logico FUNÇÃO ConverterCelsiusParaFahrenheit(ENTRADA celsius: Real): Real FUNÇÃO CalcularPrecoComDesconto(ENTRADA preco: Real, ENTRADA taxaDesconto: Real): Real ALGORITMO Principal // Suponha que celsius, preco e taxaDesconto já foram obtidos e são Real SE NÃO EstaNoIntervalo(celsius, -100, 100) ENTÃO ESCREVA "Temperatura fora do intervalo permitido" RETORNE FIM SE fahrenheit <- ConverterCelsiusParaFahrenheit(celsius) SE NÃO EstaNoIntervalo(taxaDesconto, 0, 1) ENTÃO ESCREVA "Taxa de desconto inválida" RETORNE FIM SE precoFinal <- CalcularPrecoComDesconto(preco, taxaDesconto) ESCREVA "Fahrenheit:", fahrenheit ESCREVA "Preço final:", precoFinal FIM ALGORITMOChecklist rápido de qualidade para rotinas
- O nome descreve claramente o que a rotina faz?
- A assinatura explicita direções (ENTRADA/SAÍDA/REFERÊNCIA) e tipos?
- O contrato (pré/pós) cobre limites e comportamento em entradas inválidas?
- Funções evitam efeitos colaterais (sem I/O, sem globais, sem alterar ENTRADA)?
- Procedimentos com REFERÊNCIA documentam exatamente o que é modificado?
- A rotina faz uma coisa só e pode ser reutilizada?
Exercícios
Exercício 1: validar
Crie as funções abaixo com contrato (pré/pós) e assinatura completa:
EhEmailSimples(ENTRADA texto: Texto): Logico(regra simples: contém um@e pelo menos um.após o@).EhPar(ENTRADA n: Inteiro): Logico.EstaNoIntervaloInteiro(ENTRADA valor: Inteiro, ENTRADA minimo: Inteiro, ENTRADA maximo: Inteiro): Logico.
Exercício 2: converter
Crie funções de conversão pequenas:
ConverterMinutosParaHoras(ENTRADA minutos: Inteiro): Real.NormalizarParaMaiusculas(ENTRADA texto: Texto): Texto(não altera a entrada; retorna novo texto).ConverterKmParaMetros(ENTRADA km: Real): Real.
Exercício 3: calcular
Crie funções de cálculo com validações por pré-condição:
CalcularIMC(ENTRADA pesoKg: Real, ENTRADA alturaM: Real): Real(pré: alturaM > 0).CalcularJurosSimples(ENTRADA capital: Real, ENTRADA taxa: Real, ENTRADA tempo: Inteiro): Real.CalcularMedia3(ENTRADA a: Real, ENTRADA b: Real, ENTRADA c: Real): Real.
Exercício 4: integrar em um algoritmo principal
Escreva um algoritmo principal que:
- Recebe
pesoKgealturaM(assuma que já foram lidos). - Valida
alturaMcom uma função (EstaNoIntervaloou outra criada por você). - Calcula o IMC usando
CalcularIMC. - Classifica o resultado em faixas usando uma função
ClassificarIMC(ENTRADA imc: Real): Texto. - Exibe IMC e classificação.
Regras: o algoritmo principal não deve conter a fórmula do IMC nem as regras de classificação; tudo deve estar em funções separadas com contrato.