Funções e procedimentos
Entenda como rotinas nomeadas são definidas, chamadas e devolvem controle, diferenciando funções que produzem valores de procedimentos orientados a ações.

Rotinas dão nome a uma parte executável do algoritmo
Uma rotina é um conjunto nomeado de instruções que pode ser chamado quando uma responsabilidade precisa ser executada. O nome permite pedir “calcule o subtotal” sem repetir, no fluxo principal, todos os passos necessários para fazer esse cálculo.
Em muitos materiais introdutórios, duas categorias ajudam a explicar o que o chamador espera:
- uma função produz um valor que pode ser usado em uma expressão;
- um procedimento realiza uma tarefa e devolve o controle, mas não entrega um valor ao chamador.
Essa distinção é útil, porém a terminologia depende da linguagem. Delphi e Visual Basic possuem construções separadas para função e procedimento. C# chama ambas de métodos e usa void quando não há valor. Python e JavaScript usam o termo função mesmo quando não existe um return explícito.
Por isso, primeiro compreenda o contrato da rotina: como ela é chamada, qual trabalho realiza e o que o chamador recebe ou consegue observar. Depois traduza esse contrato para a sintaxe da linguagem escolhida.
Declarar uma rotina não é o mesmo que chamá-la
A declaração registra uma receita executável. Ela reúne nome, entradas previstas, corpo e, quando aplicável, um resultado. O corpo só é executado quando ocorre uma chamada.
Considere esta função em pseudocódigo:
FUNÇÃO calcularAreaRetangulo(largura, altura): REAL
area <- largura * altura
RETORNAR area
FIM FUNÇÃO
A declaração ensina ao algoritmo como calcular uma área, mas ainda não calcula nenhuma. A execução acontece aqui:
areaDaSala <- calcularAreaRetangulo(5, 4)
Nessa chamada, os valores 5 e 4 ocupam as entradas esperadas, o corpo calcula 20, e o valor retornado passa a ocupar o lado direito da atribuição. A próxima aula diferenciará formalmente os nomes declarados e os valores enviados; por enquanto, observe apenas que a chamada fornece o contexto necessário para uma execução específica.
Se a chamada ocorrer novamente com 3 e 2, o mesmo corpo produzirá 6. A definição é uma só, mas cada chamada possui seus próprios valores e seu próprio percurso.
A chamada transfere o controle e depois o recebe de volta
Uma chamada não executa duas partes do programa ao mesmo tempo. Em um fluxo síncrono simples, ocorre esta sequência:
- o chamador chega à instrução que contém a chamada;
- os dados necessários para a chamada são obtidos;
- o controle entra no corpo da rotina;
- as instruções internas são executadas;
- a rotina termina e devolve o controle ao ponto posterior à chamada;
- se houver um valor retornado, ele substitui a chamada na expressão.
largura <- 5
altura <- 4
areaDaSala <- calcularAreaRetangulo(largura, altura)
EXIBIR areaDaSala
O comando EXIBIR não é executado enquanto o cálculo está no meio. Primeiro calcularAreaRetangulo termina; depois areaDaSala recebe 20; somente então o fluxo avança.
Essa diferença entre retorno de controle e retorno de valor é essencial. Um procedimento termina e o chamador continua, portanto o controle retornou. O que não existe, na distinção clássica, é um valor produzido para ocupar uma expressão.
Função produz um valor para o chamador usar
Uma função é adequada quando a responsabilidade pode ser formulada como uma pergunta cujo resultado será usado pelo restante do algoritmo:
- qual é o subtotal?
- esta entrada é válida?
- qual é a maior nota?
- quantos itens foram aprovados?
No fechamento de pedido da aula sobre como dividir um algoritmo em partes, o cálculo pode ser expresso assim:
FUNÇÃO calcularSubtotal(itens): REAL
subtotal <- 0
PARA CADA item DE itens FAÇA
subtotal <- subtotal + item.preco * item.quantidade
FIM PARA
RETORNAR subtotal
FIM FUNÇÃO
O chamador usa o resultado em uma atribuição:
subtotalDoPedido <- calcularSubtotal(itensValidos)
Também poderia usar a chamada dentro de uma expressão:
total <- calcularSubtotal(itensValidos) - desconto
Guardar o resultado em uma variável intermediária costuma ajudar quando ele será reutilizado, inspecionado em um teste de mesa ou combinado em etapas posteriores. Colocar a chamada diretamente na expressão é apropriado quando a leitura continua clara.
Procedimento expressa uma ação completa
Um procedimento é adequado quando a intenção principal é realizar uma ação observável, não fornecer um valor para outro cálculo:
PROCEDIMENTO exibirResumo(subtotal, desconto, total)
EXIBIR "Subtotal:", subtotal
EXIBIR "Desconto:", desconto
EXIBIR "Total:", total
FIM PROCEDIMENTO
A chamada forma uma instrução completa:
exibirResumo(subtotal, desconto, total)
A saída exibida é um efeito da execução. Ela não é um valor que substitui a chamada em uma expressão. Outros exemplos de ações são salvar um registro, enviar uma mensagem, alterar o estado de uma interface ou registrar um evento.
Isso não significa que um procedimento “não devolve nada” em qualquer sentido. Ele devolve o controle ao chamador e pode produzir efeitos que o restante do sistema observa. A formulação precisa é: na distinção clássica, o procedimento não retorna um valor ao chamador.
Use o espaço da chamada para reconhecer a intenção
Um teste simples ajuda a ler pseudocódigo e várias linguagens:
subtotal <- ________
Se calcularSubtotal(itens) preenche naturalmente esse espaço, a chamada está sendo usada como uma expressão que produz valor.
Agora observe:
________
Se exibirResumo(subtotal, desconto, total) forma sozinha uma instrução completa, sua intenção principal é executar uma ação.
O teste não substitui a documentação da linguagem. Algumas linguagens permitem chamar uma função e ignorar seu resultado; outras representam rotinas sem retorno como funções que produzem um valor especial. Ele serve para revelar o contrato desejado, não para adivinhar toda a semântica pela aparência.
A mesma intenção recebe nomes diferentes nas linguagens
Compare como uma rotina orientada a ação aparece em diferentes contextos:
| Contexto | Rotina que produz valor | Rotina sem valor útil para o chamador |
|---|---|---|
| pseudocódigo didático | FUNÇÃO | PROCEDIMENTO |
| Delphi | function | procedure |
| Visual Basic | Function | Sub |
| C# | método com tipo de retorno | método void |
| Python | função com return valor | função sem retorno explícito produz None |
| JavaScript | função com return valor | função sem retorno explícito produz undefined |
Em C#, a distinção pode aparecer no tipo declarado:
decimal CalcularTotal(decimal subtotal, decimal desconto)
{
return subtotal - desconto;
}
void ExibirTotal(decimal total)
{
Console.WriteLine($"Total: {total:C}");
}
Já em Python, as duas rotinas são declaradas com def:
def calcular_total(subtotal, desconto):
return subtotal - desconto
def exibir_total(total):
print(f"Total: {total:.2f}")
calcular_total(200, 20) produz 180. exibir_total(180) mostra uma saída e, por não possuir return explícito, também produz implicitamente None. Isso não transforma None no resultado de negócio desejado; é a maneira como Python modela o término de uma função sem outro valor.
Em JavaScript, uma função que chega ao fim sem return com expressão produz undefined. Portanto, use a palavra “procedimento” como categoria didática quando ela ajudar, mas consulte a construção real da linguagem em que estiver programando.
Escolha o contrato antes da sintaxe
Para decidir a forma de uma rotina, pergunte primeiro como o chamador precisa colaborar com ela:
| Pergunta | Tendência de contrato |
|---|---|
| o chamador precisa combinar o resultado em outro cálculo? | produzir e retornar um valor |
| o resultado representa uma consulta, transformação ou decisão? | produzir e retornar um valor |
| a responsabilidade principal é comunicar, persistir ou acionar algo? | executar uma ação |
| o chamador precisa saber se a ação funcionou? | a ação pode precisar devolver um estado explícito ou comunicar falha por outro mecanismo |
Uma rotina que salva um pedido, por exemplo, pode apenas realizar a ação em um exercício simples. Em um sistema real, talvez precise entregar um identificador ou comunicar uma falha. A escolha não vem do verbo isolado; vem das informações necessárias para o chamador continuar corretamente.
Evite usar efeitos ocultos como substitutos convenientes para resultados. Se calcularSubtotal altera silenciosamente uma variável global em vez de retornar o subtotal, o chamador passa a depender de um estado que não aparece na chamada. Isso dificulta compreender entradas, saídas e testes.
O modelo de entrada, processamento e saída ajuda a explicitar o contrato: determine o que entra, qual transformação ocorre e se a saída será um valor retornado ou um efeito observável.
Evite quatro confusões frequentes
Achar que a declaração já executou o corpo
Definir calcularSubtotal disponibiliza a rotina. Cada cálculo acontece somente quando uma chamada é alcançada pelo fluxo.
Confundir saída exibida com valor retornado
EXIBIR total envia informação ao dispositivo de saída. RETORNAR total entrega um valor ao trecho que chamou a rotina. Uma função pode fazer ambos, mas são operações diferentes.
Ignorar um resultado importante
Algumas linguagens permitem chamar uma função como instrução isolada:
calcularSubtotal(itensValidos)
O cálculo acontece, mas seu valor pode ser descartado. Se o resultado é necessário, atribua-o ou use-o explicitamente.
Criar nomes que escondem o contrato
processarPedido não permite prever se a rotina valida, calcula, salva ou exibe. Nomes como calcularSubtotal, pedidoEhValido e exibirResumo tornam valor ou ação mais fáceis de antecipar.
Pratique montando um pequeno coordenador
Organize um algoritmo de boletim usando estas responsabilidades:
- calcular a média de quatro notas;
- decidir a situação a partir da média;
- exibir média e situação.
Primeiro classifique cada responsabilidade como produtora de valor ou orientada a ação. Depois complete o coordenador:
media <- __________________________
situacao <- _______________________
__________________________________
Uma solução possível é:
media <- calcularMedia(notas)
situacao <- classificarSituacao(media)
exibirBoletim(media, situacao)
Verifique a execução com as notas 8, 7, 6 e 9: a média deve ser 7,5; essa média alimenta a classificação; e a apresentação só acontece depois que os dois valores existem. Em seguida, faça uma segunda chamada com outras notas para confirmar que a mesma declaração atende execuções independentes.
O que você deve guardar
Funções e procedimentos são formas de encapsular uma responsabilidade em uma rotina nomeada. Declarar registra o corpo; chamar transfere o controle para ele; terminar devolve o controle ao chamador. Na distinção didática clássica, a função também entrega um valor, enquanto o procedimento realiza uma ação sem retornar valor.
Trate essa diferença como um modelo de contrato, não como vocabulário universal. C#, Python e JavaScript representam rotinas sem valor de maneiras diferentes. Antes de escolher a sintaxe, determine o que o chamador precisa fornecer, observar e usar. Na próxima aula, aprofunde a relação entre parâmetros e argumentos para compreender como cada chamada preenche as entradas declaradas.
Referências
- Embarcadero — Procedures and Functions (Delphi). Acesso em 11 set. 2026.
- Microsoft Learn — Methods (C# Programming Guide). Acesso em 11 set. 2026.
- Python 3 Documentation — Defining Functions. Acesso em 11 set. 2026.
- MDN Web Docs — JavaScript language overview: Functions. Acesso em 11 set. 2026.