1. Por que dividir um algoritmo em pedaços
Até aqui, todo algoritmo deste módulo coube em um único bloco de
INÍCIO...FIM. Isso funciona para exemplos pequenos, mas um
programa real — um sistema de vendas, um app de banco — tem milhares de linhas. Ler tudo
isso como um bloco único seria inviável. A solução é a mesma que engenheiros usam para
qualquer sistema complexo: quebrar o problema grande em pedaços menores, cada um
com uma responsabilidade clara.
Esses pedaços nomeados e reutilizáveis são chamados de funções e procedimentos. Modularizar um algoritmo traz três ganhos concretos:
- Reuso — escreva a lógica de "calcular o frete" uma vez, chame de vários lugares do programa.
- Legibilidade — um algoritmo principal que chama
validarCPF(cpf)é mais fácil de entender de relance do que o mesmo algoritmo com a validação inteira despejada no meio do fluxo. - Testabilidade — é muito mais fácil testar um pedaço pequeno e isolado do que um algoritmo gigante inteiro de uma vez.
2. Função vs. procedimento
A distinção é simples e universal: uma função devolve um valor para quem a chamou; um procedimento executa uma ação mas não devolve nada.
| Função | Procedimento | |
|---|---|---|
| Devolve valor? | Sim, sempre | Não |
| Uso típico | total ← calcularTotal(preco, qtd) | imprimirRecibo(total) |
| Pensamento | "Me dê um valor calculado a partir disso" | "Faça algo com isso" |
FUNÇÃO calcularMedia(nota1, nota2, nota3)
media ← (nota1 + nota2 + nota3) / 3
RETORNE media
FIM FUNÇÃO
INÍCIO
resultado ← calcularMedia(7, 8, 9)
ESCREVA "Média: " + resultado
FIM
PROCEDIMENTO exibirBoasVindas(nome)
ESCREVA "Olá, " + nome + "! Seja bem-vindo."
FIM PROCEDIMENTO
INÍCIO
exibirBoasVindas("Ana")
exibirBoasVindas("Wellington")
FIM
Em JavaScript, essa distinção não é forçada pela sintaxe — toda function
pode ou não ter return. Se não tiver, ela devolve
undefined por baixo dos panos, o que na prática já é o
comportamento de um procedimento. Outras linguagens (como C#, com void
para "não devolve nada") deixam essa diferença explícita na assinatura. O conceito é o
mesmo — só a obrigatoriedade sintática muda.
3. Parâmetros
Parâmetros são os valores que uma função ou procedimento recebe de quem a
chama, para trabalhar com eles internamente. No exemplo da seção anterior,
nota1, nota2 e
nota3 são parâmetros de calcularMedia.
Cada vez que a função é chamada, os parâmetros recebem os valores passados naquela chamada
específica — é assim que a mesma função consegue calcular médias diferentes sem precisar
ser reescrita.
FUNÇÃO ehMaiorDeIdade(idade)
SE idade >= 18 ENTÃO
RETORNE VERDADEIRO
SENÃO
RETORNE FALSO
FIM SE
FIM FUNÇÃO
INÍCIO
ESCREVA ehMaiorDeIdade(20) // VERDADEIRO
ESCREVA ehMaiorDeIdade(15) // FALSO
FIM
Uma função pode receber zero, um ou vários parâmetros. Quando não recebe nenhum
(FUNÇÃO gerarNumeroAleatorio()), ela ainda pode devolver um
valor diferente a cada chamada, dependendo de alguma lógica interna.
4. Escopo local vs. global
Escopo é a região do algoritmo onde uma variável "existe" e pode ser usada. Existem dois níveis básicos:
- Escopo local — uma variável criada dentro de uma função ou procedimento só existe ali dentro. Quando a função termina, a variável "desaparece".
- Escopo global — uma variável criada fora de qualquer função existe durante todo o algoritmo, e pode (com cuidado) ser acessada de qualquer lugar.
total ← 0 // variável global
FUNÇÃO dobrar(numero)
resultado ← numero * 2 // variável local, só existe aqui dentro
RETORNE resultado
FIM FUNÇÃO
INÍCIO
total ← dobrar(5)
ESCREVA total // funciona: total é global
ESCREVA resultado // ERRO: resultado só existe dentro de dobrar
FIM
Depender de variáveis globais dentro de funções é considerado má prática na maioria dos casos — torna difícil saber, só de olhar a função, de onde vêm os dados que ela usa. Prefira sempre passar os dados necessários como parâmetros explícitos. Essa regra vale em qualquer linguagem que você for programar depois.
5. Recursão, brevemente
Existe um caso especial em que uma função chama a si mesma — isso se chama recursão. É uma técnica poderosa para resolver problemas que se repetem em versões menores de si mesmos (como calcular um fatorial, ou percorrer uma estrutura em árvore), mas exige cuidado redobrado com a condição de parada — do contrário, vira uma espécie de "loop infinito" de chamadas de função.
Este módulo só menciona recursão de passagem: o assunto merece atenção própria e volta com profundidade no Módulo 3 — Algoritmos e Estruturas de Dados, quando você já tiver a base matemática necessária para entender por que ela funciona.
6. Onde isso te leva
Com este capítulo, você fecha o vocabulário universal da lógica de programação: algoritmo, pseudocódigo, fluxograma, variável, tipo de dado, operador, decisão, repetição e modularização. Esses nove conceitos, combinados, são a base de qualquer programa que já foi escrito, em qualquer linguagem, para qualquer plataforma. Você agora consegue ler um problema em português e traduzi-lo para um algoritmo estruturado antes de escrever uma única linha de código real — e é exatamente essa habilidade que separa quem só decora sintaxe de quem realmente sabe programar.
O próximo módulo, Módulo 2 — Matemática para Programação, aprofunda a
base formal por trás de tudo que você viu aqui: lógica proposicional (o "porquê" formal por
trás do E, OU e
NÃO deste capítulo), álgebra booleana, e sistemas de
numeração (como o computador realmente representa os tipos inteiro, real e lógico que você
aprendeu no Capítulo 3). Depois dele, o Módulo 3 — Algoritmos e Estruturas de
Dados usa essa base matemática para ensinar estruturas mais ricas de organização
de dados, complexidade de algoritmos, e recursão a fundo. Só então o curso chega ao
Módulo 4, onde toda essa fundação vira C# de verdade.