Semana 05 — Modularização de código¶
Nesta semana
Unidade 2 · Seg 07/09 · Qua 09/09 · Sex 11/09 · ⚠️ feriado: 07/09 (Independência)
Na Semana 04 você aprendeu a quebrar um programa em funções. Agora damos o passo
seguinte e maior: quebrar o programa em vários arquivos. Um projeto de verdade
raramente cabe em um único .c — ele se organiza em módulos, cada um com um
conjunto de funções relacionadas, sua interface (o cabeçalho .h) e sua
implementação (o .c). Essa é a forma como praticamente todo software profissional
em C é escrito.
Aqui você vai entender por que separar código dessa maneira, o que vai em um .h e
o que vai em um .c, como o #include e o pré-processador realmente funcionam, o que
são as guardas de inclusão, e como compilar e ligar vários arquivos com o gcc.
Como sempre: digite, compile e execute cada exemplo. Modularização se aprende
montando o projeto com as próprias mãos.
🎯 Objetivos de aprendizagem¶
Ao final desta semana, você deverá ser capaz de:
- explicar por que dividir um programa em vários arquivos (tamanho, reuso entre projetos, trabalho em equipe, recompilação parcial);
- distinguir protótipo (declaração) de definição, e saber o que vai no
.he o que vai no.c; - escrever um cabeçalho (
.h) com protótipos,#defineestruct, protegido por guarda de inclusão; - usar corretamente o
#includecom aspas duplas ("meu.h") e com<>, e explicar que o pré-processador apenas cola texto; - compilar separadamente (
gcc -c) e ligar (gcc *.o -o prog) um projeto de vários arquivos, tanto no terminal quanto no Code::Blocks (como Project); - entender a ideia de um
Makefilepara automatizar a compilação; - organizar um mini-projeto em módulos coesos, seguindo boas práticas.
📖 Segunda — Estudo do conteúdo¶
1. Por que dividir um programa em vários arquivos?¶
Até agora, todos os seus programas moraram em um único arquivo .c. Para os exercícios
que fizemos, isso é perfeitamente adequado. Mas imagine um programa com milhares de
linhas: um sistema de biblioteca, um jogo, um compilador. Manter tudo num arquivo só
rapidamente se torna insustentável. A modularização — dividir o programa em vários
arquivos, cada um cuidando de uma parte — resolve quatro problemas concretos:
- Programas grandes ficam navegáveis. Um arquivo de 5.000 linhas é impossível de ler.
Dividido em
entrada.c,calculo.c,relatorio.c, cada arquivo é pequeno, coeso e fácil de entender. Você sabe onde procurar cada coisa. - Reuso entre projetos. Se você escreve um módulo
mat.c/mat.hcom funções matemáticas úteis, pode copiar esses dois arquivos para outro projeto e usá-los imediatamente, sem recortar-e-colar funções soltas. É assim que nascem as bibliotecas. - Trabalho em equipe. Numa equipe, cada pessoa pode trabalhar em um módulo diferente
ao mesmo tempo, sem ficar tropeçando no arquivo do colega. As interfaces (os
.h) definem o "contrato" entre os módulos. - Recompilar só o que mudou. Este é um ganho técnico enorme. Se você alterou apenas
calculo.c, o compilador precisa recompilar somente esse arquivo e depois religar o programa — os demais permanecem intactos. Num projeto grande, isso é a diferença entre esperar 1 segundo ou vários minutos a cada alteração.
Curiosidade 💡 — por que .h e .c separados? (um pouco de história)
A separação entre interface (.h) e implementação (.c) nasceu com o próprio
C, nos anos 1970, para permitir a compilação separada: cada .c podia ser
compilado sozinho, sabendo apenas dos protótipos das funções que estavam em outros
arquivos. Naquela época, computadores eram lentos e recompilar tudo levava muito tempo —
poder compilar só o arquivo modificado era essencial. Essa ideia de separar "o que um
módulo oferece" (interface) de "como ele faz" (implementação) sobreviveu e é hoje um dos
pilares da engenharia de software, presente em praticamente todas as linguagens.
2. Recapitulando: protótipo × definição¶
Antes de espalhar código por vários arquivos, precisamos revisitar um conceito da Semana 04: a diferença entre declarar e definir uma função.
- Um protótipo (ou declaração) é a assinatura da função — tipo de retorno,
nome e tipos dos parâmetros — seguida de
;. Ele promete ao compilador que a função existe em algum lugar, sem dizer como ela funciona. - A definição é a implementação de verdade: a assinatura seguida do corpo
{ ... }.
double media(double a, double b); // PROTÓTIPO (declaração): termina em ;
double media(double a, double b) { // DEFINIÇÃO: tem corpo { ... }
return (a + b) / 2.0;
}
A chave da modularização está aqui: para usar uma função, o compilador só precisa
conhecer o seu protótipo. A definição pode estar em outro arquivo, compilado
separadamente, e será encontrada na etapa de ligação (a mesma etapa 4 da compilação que
vimos na Semana 01). Ou seja: colocamos os protótipos num
lugar que todos os arquivos podem "enxergar" (o .h), e as definições ficam guardadas
no .c.
3. Cabeçalho (.h) e implementação (.c): o que vai em cada um¶
A partir de agora, um módulo será, tipicamente, um par de arquivos de mesmo nome:
- Um cabeçalho
nome.h(header) — a interface do módulo: o que ele oferece ao mundo externo. - Uma implementação
nome.c— o como: o código real das funções.
O que vai em cada um:
Vai no cabeçalho (.h) |
Vai na implementação (.c) |
|---|---|
| Protótipos das funções públicas | Definições (corpos) das funções |
#define (constantes e macros públicas) |
Variáveis e funções auxiliares (uso interno) |
Definições de struct e typedef |
O #include "nome.h" do próprio módulo |
| Comentários explicando como usar cada função | Detalhes de implementação que ninguém "de fora" precisa ver |
A regra mental é simples: o .h diz o QUE o módulo faz; o .c diz COMO ele faz.
Quem for usar o seu módulo lê apenas o .h — ele não precisa (nem deve) se preocupar
com os detalhes do .c. Isso é a abstração da Semana 04, agora aplicada em escala de
arquivos.
Regra de ouro: NÃO defina (implemente) funções no .h
No cabeçalho vão apenas protótipos (declarações que terminam em ;). A
implementação (o corpo { ... }) vai no .c. Colocar o corpo de uma função no
.h costuma provocar erros de "definição múltipla" (multiple definition) quando
mais de um .c inclui esse cabeçalho — pois cada inclusão traz uma cópia da função. No
.h, só a promessa; no .c, a entrega.
4. O #include: "aspas" × <colchetes>¶
Você usa o #include desde a Semana 01 (#include <stdio.h>). Agora vamos entender o que
ele realmente faz — e as duas formas de escrevê-lo:
#include <stdio.h> // biblioteca do SISTEMA -> colchetes < >
#include "mat.h" // arquivo do SEU PROJETO -> aspas duplas " "
<arquivo.h>(colchetes angulares): usado para os cabeçalhos das bibliotecas do sistema (a biblioteca-padrão do C:stdio.h,stdlib.h,math.h, ...). O pré-processador procura esses arquivos nos diretórios padrão do compilador."arquivo.h"(aspas duplas): usado para os cabeçalhos do seu próprio projeto. O pré-processador procura primeiro na pasta do arquivo atual e depois nos diretórios padrão.
A regra prática é fácil: é seu, use aspas; é do sistema, use colchetes.
Curiosidade 💡 — o pré-processador só faz 'copiar e colar' texto
Aqui vai algo que surpreende muita gente: o #include não é mágica. Na primeira
etapa da compilação (o pré-processamento, Semana 01), o pré-processador simplesmente
abre o arquivo indicado e cola o seu conteúdo inteiro no lugar da linha #include,
como se você tivesse feito um copiar-colar. Depois disso, o #include desaparece — o
compilador nem sabe que ele existiu. O mesmo vale para o #define: ele apenas troca
texto por texto antes da compilação de verdade. Entender que o pré-processador é um
"editor de texto automático" desmistifica quase todos os erros ligados a #.
5. Guardas de inclusão (#ifndef / #define / #endif)¶
Como o #include cola o conteúdo do arquivo, surge um problema. Imagine três arquivos:
mat.h— define umastruct Ponto.geom.h— usaPonto, então faz#include "mat.h".main.c— usa os dois, então faz#include "mat.h"e#include "geom.h".
Ao processar main.c, o pré-processador cola mat.h (por causa do primeiro include) e,
logo depois, cola geom.h, que por sua vez cola mat.h de novo. Resultado: a
struct Ponto aparece duas vezes — e o compilador reclama de redefinição. Isso é a
inclusão dupla (ou inclusão múltipla).
A solução é a guarda de inclusão (include guard): um trio de diretivas que faz o conteúdo do cabeçalho ser processado uma única vez, não importa quantas vezes ele seja incluído:
#ifndef MAT_H // "if not defined": se MAT_H ainda NÃO foi definido...
#define MAT_H // ...define MAT_H (uma marca) e processa o conteúdo abaixo
// ... todo o conteúdo do cabeçalho: protótipos, #define, structs ...
#endif // fim do bloco protegido
Como funciona, passo a passo:
- Na primeira vez que
mat.hé incluído,MAT_Hainda não existe, então o#ifndefé verdadeiro: o#define MAT_Hcria a "marca" e todo o conteúdo é processado. - Numa segunda inclusão (na mesma compilação),
MAT_Hjá está definido, o#ifndefé falso, e o pré-processador pula tudo até o#endif. O conteúdo não é colado de novo.
Por convenção, o nome da marca é o nome do arquivo em MAIÚSCULAS, com o ponto virando
_: mat.h → MAT_H; minha_lista.h → MINHA_LISTA_H. Todo cabeçalho que você
escrever deve ter uma guarda de inclusão — é um hábito automático.
Curiosidade 💡 — #pragma once, o atalho moderno
Muitos compiladores aceitam uma alternativa mais curta à guarda de inclusão: basta escrever, na primeira linha do cabeçalho:
Ele tem o mesmo efeito — o arquivo é incluído uma só vez. É mais curto e não exige inventar um nome de marca. A pegadinha é que o#pragma once não faz parte do padrão
oficial do C (embora seja suportado por praticamente todos os compiladores atuais,
incluindo o gcc). O trio #ifndef/#define/#endif é 100% portável e por isso
ainda é o mais ensinado. Conheça os dois; use o que preferir (ou o que a equipe adotar).
6. Compilação separada com o gcc¶
Com o código dividido em vários .c, como transformá-los num único executável? Há duas
maneiras equivalentes.
Modo direto (tudo de uma vez): passe todos os .c para o gcc. Ele compila cada um e
liga tudo num só comando:
Modo em duas etapas (compilar, depois ligar): este modo revela o que acontece por baixo
e é a base da recompilação parcial. Primeiro, gera-se um arquivo-objeto (.o) para
cada .c com a flag -c (que significa "compile, mas não ligue ainda"):
Depois, liga-se todos os .o num executável (etapa de linking):
A vantagem: se depois você mudar apenas mat.c, basta recompilar mat.c (gerando um
novo mat.o) e religar — não é preciso recompilar main.c. É exatamente o ganho
"recompilar só o que mudou" da seção 1.
flowchart LR
subgraph fontes["Código-fonte (.c) e cabeçalho (.h)"]
A["main.c"]
B["mat.c"]
H["mat.h"]
end
H -.incluido por.-> A
H -.incluido por.-> B
A -->|gcc -c| AO["main.o"]
B -->|gcc -c| BO["mat.o"]
AO -->|ligacao| E["prog<br/>(executavel)"]
BO -->|ligacao| E
No Code::Blocks, isso é um 'Project'
No terminal você lista os arquivos à mão; no Code::Blocks, essa organização se chama
Project. Em vez de abrir um .c solto, você cria um File → New → Project → Console
application e vai adicionando os arquivos a ele (Project → Add files...). Ao
apertar F9, o Code::Blocks compila todos os .c do projeto e liga tudo
automaticamente — ele monta os comandos gcc por você. Se o seu programa tem mais de um
.c, você precisa de um Project; abrir só um dos arquivos e compilar dará o erro de
undefined reference que veremos na seção 11.
7. A ideia de um Makefile¶
Digitar os comandos gcc -c para cada arquivo e depois o comando de ligação, toda vez, é
cansativo e sujeito a erro. Em projetos reais usa-se uma ferramenta chamada make, que
lê um arquivo de receita chamado Makefile e automatiza a compilação. Você não
precisa dominar make nesta disciplina — basta ter a ideia: o Makefile descreve
quais arquivos dependem de quais, e o make é esperto o bastante para recompilar apenas
o que mudou.
prog: main.o mat.o
gcc main.o mat.o -o prog
main.o: main.c mat.h
gcc -c main.c
mat.o: mat.c mat.h
gcc -c mat.c
Com esse arquivo na pasta, basta digitar make no terminal e todo o processo acontece. Se
você mudar só mat.c, o make recompila apenas mat.o e religa. Por ora, guarde só o
conceito: make = automatizar a compilação de projetos com vários arquivos.
8. Um mini-projeto completo, do começo ao fim¶
Vamos juntar tudo num exemplo completo e correto: um pequeno módulo de matemática
(mat.h + mat.c) usado por um programa principal (main.c). Estude os três arquivos como
um conjunto.
Primeiro, a interface — só protótipos, uma constante e a guarda de inclusão:
#ifndef MAT_H
#define MAT_H
// Constante publica do modulo
#define MAT_PI 3.14159265358979
// Protótipos das funções oferecidas pelo módulo:
int soma(int a, int b); // devolve a + b
long fatorial(int n); // devolve n! (n >= 0)
int eh_primo(int n); // 1 se n e primo, 0 caso contrario
double area_circulo(double raio); // area de um circulo de dado raio
#endif
Agora a implementação — os corpos das funções. Note que mat.c inclui o próprio
mat.h: assim o compilador confere se as definições batem com os protótipos.
#include "mat.h" // o modulo inclui o seu proprio cabecalho
int soma(int a, int b) {
return a + b;
}
long fatorial(int n) {
long resultado = 1;
for (int i = 2; i <= n; i++) {
resultado *= i;
}
return resultado; // 0! e 1! resultam em 1 (o laco nem executa)
}
int eh_primo(int n) {
if (n < 2) {
return 0; // 0 e 1 nao sao primos
}
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
return 0; // achou um divisor -> nao e primo
}
}
return 1;
}
double area_circulo(double raio) {
return MAT_PI * raio * raio; // usa a constante do proprio cabecalho
}
Por fim, o programa principal — ele inclui mat.h e usa as funções, sem precisar saber
como elas foram implementadas:
#include <stdio.h>
#include "mat.h" // aspas: e um cabecalho do nosso projeto
int main(void) {
int a, b;
printf("Digite dois inteiros: ");
scanf("%d %d", &a, &b);
printf("Soma = %d\n", soma(a, b));
int n;
printf("Digite n para o fatorial: ");
scanf("%d", &n);
printf("%d! = %ld\n", n, fatorial(n));
printf("Primos de 2 a 20: ");
for (int i = 2; i <= 20; i++) {
if (eh_primo(i)) {
printf("%d ", i);
}
}
printf("\n");
double raio;
printf("Raio do circulo: ");
scanf("%lf", &raio); // %lf na LEITURA de double
printf("Area = %.2f\n", area_circulo(raio));
return 0;
}
Para compilar e executar este projeto no terminal:
gcc -Wall -std=c11 -c mat.c # gera mat.o
gcc -Wall -std=c11 -c main.c # gera main.o
gcc mat.o main.o -o prog # liga tudo
./prog
Ou, de uma vez só: gcc -Wall -std=c11 main.c mat.c -o prog. No Code::Blocks, crie um
Project e adicione main.c e mat.c (o mat.h é incluído automaticamente por estar na
mesma pasta). Repare como o main.c ficou limpo: ele conta a "história" do programa e
delega os cálculos ao módulo mat.
Exercício-relâmpago mental
Onde está a definição da função fatorial? E o seu protótipo? Se você quisesse mudar
o cálculo do fatorial (por exemplo, de laço para recursão — Semana 06), qual arquivo
precisaria alterar, e qual arquivo não mudaria em nada? Responder isso é entender a
separação interface/implementação.
9. Boas práticas de organização de código¶
- Um módulo, um assunto. Agrupe no mesmo par
.h/.cfunções que tratam do mesmo tema (tudo de matemática emmat, tudo de strings emstrutil). Isso é chamado de coesão. .hmínimo e público. No cabeçalho, exponha apenas o que quem usa o módulo precisa ver. Funções auxiliares, usadas só internamente, ficam apenas no.c(sem protótipo no.h).- Sempre uma guarda de inclusão em todo
.h— sem exceção. - O
.cinclui o seu próprio.h. Além de organizado, isso deixa o compilador conferir se as implementações batem com os protótipos. - Nomes de arquivo iguais aos do módulo.
lista.h/lista.c, e nãoheader1.h. - Comente a interface, não a implementação óbvia. No
.h, um comentário curto ao lado de cada protótipo dizendo o que a função faz e o que ela espera vale ouro. - Compile sempre com
-Wall. Os avisos do compilador apontam problemas de interface (tipos que não batem, protótipo ausente) antes que virem bugs.
10. Erros comuns desta semana (resumão)¶
Checklist de armadilhas
- Esquecer a guarda de inclusão (
#ifndef/#define/#endif) no.h→ erro de redefinição por inclusão dupla. - Definir (implementar) uma função no
.hem vez de só declará-la → erro de múltipla definição (multiple definition) na ligação. No.h, só protótipos. - Esquecer de compilar/ligar o
.cde um módulo → erroundefined referencena etapa de ligação (a etapa 4 da Semana 01). O compilador conhece o protótipo, mas não encontrou a definição porque o.cnão entrou na compilação. No Code::Blocks, isso quase sempre significa que você não criou um Project (ou não adicionou o arquivo a ele). - Incluir o
.cem vez do.h(#include "mat.c") → cola o código-fonte inteiro e provoca múltipla definição ao ligar. Inclua sempre o.h. - Nome da marca da guarda repetido em dois cabeçalhos diferentes (copiar-colar sem trocar o nome) → um dos cabeçalhos é silenciosamente ignorado.
👥 Quarta — Encontro¶
Chegue ao encontro tendo estudado o material e, principalmente, tendo montado e executado o mini-projeto da seção 8 na sua máquina. Modularização só "entra na cabeça" quando você vê os arquivos se ligando de verdade. Roteiro previsto:
- Revisão relâmpago: protótipo × definição, o que vai no
.h× no.c, e o papel das guardas de inclusão. - Ao vivo: partir de um programa "tudo num
.c" e extrair um módulo (.h+.c), compilando em duas etapas para ver os.osurgirem. - Galeria de erros: provocamos de propósito o
undefined reference, a múltipla definição (implementando no.h) e a inclusão dupla (removendo a guarda), para você aprender a ler e localizar cada um — e saber em qual etapa (compilação ou ligação) ele acontece.
Problema-guia do encontro — módulo de conversões: vamos criar um módulo conv com
funções de conversão de unidades, e um main.c que o usa. Estrutura de partida:
#ifndef CONV_H
#define CONV_H
double celsius_para_fahrenheit(double c); // F = C * 9/5 + 32
double fahrenheit_para_celsius(double f); // C = (F - 32) * 5/9
double km_para_milhas(double km); // 1 km = 0.621371 milhas
double milhas_para_km(double mi);
#endif
No encontro, implementaremos conv.c juntos (atenção à divisão real: use 9.0/5.0,
não 9/5) e escreveremos um main.c com um pequeno menu que lê a opção do usuário e chama
a conversão certa. Perguntas para pensar antes: por que conv.c deve incluir conv.h? O
que aconteceria se removêssemos a guarda de inclusão de conv.h e dois arquivos o
incluíssem?
✍️ Sexta — Estudo dirigido¶
Atenção: o juiz Beecrowd usa um único arquivo
A modularização em .h/.c não é testada diretamente no Beecrowd: o juiz aceita a
submissão de um único arquivo-fonte. Ou seja, você não sobe projetos
multi-arquivo lá. Isso não torna o tema menos importante — é exatamente o oposto: a
modularização é uma habilidade de projeto local, que você pratica montando projetos
de verdade na sua máquina. Por isso, o foco desta sexta são os Desafios para escrever
do zero (projetos multi-arquivo locais). A tabela do Beecrowd abaixo serve para
treinar a boa decomposição em funções, que é a base da modularização.
Exercícios guiados (Beecrowd)¶
A ideia aqui é reforçar a decomposição em funções bem separadas — o passo anterior a espalhá-las por módulos. Refaça exercícios já conhecidos das semanas anteriores, agora organizando o código em funções pequenas, coesas e bem nomeadas (mesmo que, no Beecrowd, tudo fique num só arquivo).
| Nº | Problema | Como organizar em funções |
|---|---|---|
| 1153 | Fatorial Simples | isole long fatorial(int n) — a mesma que iria num módulo mat |
| 1165 | Números Primos | isole int eh_primo(int n) e use-a no laço principal |
| 1157 | Divisores | int conta_divisores(int n), candidata a um módulo mat |
| 1478 | Tabela de Multiplicação | void imprime_tabuada(int n) reutilizável |
| 1176 | Fibonacci Array | long fibonacci(int n) bem isolada |
Ao resolver, pergunte-se: "se eu fosse mover esta função para um mat.h/mat.c, qual seria
o protótipo?". Se a resposta é imediata, sua função está bem desenhada.
Desafios para escrever do zero (projetos multi-arquivo, na sua máquina)¶
Estes são o coração da semana. Monte cada um como um projeto de verdade, com
cabeçalho, implementação e main separados, e compile em duas etapas (gcc -c + ligação)
ou como um Project no Code::Blocks.
- Biblioteca de matemática (
mat.h+mat.c): parta do mini-projeto da seção 8 e acrescente funções:int mdc(int a, int b),int mmc(int a, int b),long potencia(int base, int expoente)eint eh_perfeito(int n). Escreva ummain.cque exercite todas. Todo protótipo novo entra no.h; toda implementação, no.c. - Biblioteca de utilidades de string (
strutil.h+strutil.c): crie funções comoint tamanho(const char s[])(conta caracteres até o\0),int conta_vogais(const char s[])evoid para_maiusculas(char s[]). (Strings são o tema da Semana 08 — aqui você pode começar com o básico e voltar para incrementar depois.) - Reorganize um exercício antigo em módulos: pegue um programa maior que você já
escreveu (por exemplo, a calculadora com menu da Semana 04) e quebre-o em módulos:
um
operacoes.h/operacoes.ccom as contas e ummain.csó com o menu e a E/S. Compare a legibilidade domain.cantes e depois. - Módulo de geometria (
geom.h+geom.c): funções de área e perímetro de retângulo, círculo e triângulo, mais uma constante#define GEOM_PI 3.14159. Faça omain.cimprimir um pequeno relatório usando o módulo.
Para investigar (curiosidade prática)¶
- Monte o projeto da seção 8 e compile em duas etapas. Depois, altere só
mat.c, recompile apenasmat.oe religue. Confirme quemain.onão precisou ser recompilado. - Provoque o erro
undefined referencede propósito: compile e ligue esquecendo omat.o(gcc main.o -o prog). Leia a mensagem do ligador. Em qual etapa o erro ocorre? - Remova a guarda de inclusão de um
.hque seja incluído por dois arquivos diferentes e observe o erro de redefinição. Depois recoloque a guarda e confirme que some. - Crie um
.he inclua-o duas vezes no mesmo.c(#include "mat.h"repetido). Com a guarda, nada de ruim acontece. Entenda por quê.
✅ Checklist de autoavaliação¶
Marque com sinceridade — se algum item não estiver ✅, volte à seção correspondente.
- Explico por que dividir um programa em vários arquivos (tamanho, reuso, equipe, recompilar só o que mudou).
- Sei o que vai no
.h(protótipos,#define,struct) e o que vai no.c(implementações). - Uso
#includecom aspas para arquivos do projeto e<>para o sistema, e sei que o pré-processador apenas cola texto. - Escrevo um cabeçalho protegido por guarda de inclusão e explico o problema da
inclusão dupla (e conheço o
#pragma once). - Compilo separadamente (
gcc -c) e ligo (gcc *.o -o prog) um projeto de vários arquivos; sei que no Code::Blocks isso é um Project. - Tenho a ideia do que um
Makefileautomatiza. - Reconheço e sei corrigir os erros de
undefined reference, múltipla definição e redefinição por inclusão dupla.
🔗 Referências e para se aprofundar¶
- Material 2026.1 — Aula 15: Modularização de Código.
- BACKES, André. Linguagem C: completa e descomplicada (organização de programas, cabeçalhos e compilação separada).
- KERNIGHAN, B.; RITCHIE, D. The C Programming Language (o clássico "K&R"), cap. 4 (escopo externo, cabeçalhos e o pré-processador — seção 4.11).
- Referência: cppreference — Preprocessor
(detalhes de
#include,#definee#pragma once). - Prática: Beecrowd (para treinar a decomposição em funções — lembre-se: submissão em arquivo único).
Antes de seguir para a Semana 06
Você agora sabe organizar o código em módulos — o que o QUE fica separado do COMO. Na
próxima semana vamos explorar uma ideia poderosa e elegante que costuma "quebrar a
cabeça" de quem vê pela primeira vez: a recursão, funções que chamam a si mesmas.
Lembra da pilha de chamadas que citamos na Semana 04? Ela é a peça-chave para
entender como uma função pode se chamar sem se perder. Traga o fatorial que você
escreveu esta semana — na Semana 06 ele vai renascer em versão recursiva.