Caderno de Exercícios¶
Estruturas de Dados Lineares e Gestão de Memória em C¶
1. 🎯 Introdução e Contextualização¶
O domínio de ponteiros, alocação dinâmica e da correta arquitetura de Tipos Abstratos de Dados (TADs) é um divisor de águas entre um programador iniciante e um engenheiro de computação.
Na prática:
- Eficiência não é acidental → é resultado de decisões conscientes
- Organização de dados impacta diretamente o desempenho
- Gestão de memória é crítica para estabilidade e segurança
Um código que funciona em pequena escala pode falhar sob carga se:
- houver uso incorreto do heap
- faltar encapsulamento
- não existir controle do ciclo de vida da memória
O objetivo deste caderno é fazer você pensar como arquiteto de software, não apenas como programador.
2. 📏 Critérios de Avaliação (Rigor Arquitetural)¶
Para que uma solução seja considerada correta:
Segurança de Alocação¶
- Sempre verificar o retorno de
malloc,callocourealloc NULLnão tratado = erro crítico
Gestão de Memória (Accountability)¶
- Todo
mallocdeve ter umfree - Vazamento de memória = falha grave
Encapsulamento¶
main.cdeve usar apenas funções do.h- Acesso direto à struct = violação de projeto
Sem Variáveis Globais¶
- Comunicação entre módulos → via parâmetros e retornos
3. 🧠 Parte I — Fundamentos Teóricos (11 Questões)¶
Conceito central¶
Separar:
- O que fazer (interface) →
.h - Como fazer (implementação) →
.c
Questões¶
-
Passagem por valor vs referência
Explique por que funções como
empilha(Pilha *p, int x)usam ponteiros.O que aconteceria se a pilha fosse passada por valor?
-
Stack vs Heap
Diferencie:
- Stack (automática)
- Heap (dinâmica)
Quem gerencia cada uma?
Por que retornar variável local é perigoso?
-
Tipo Abstrato de Dado (TAD)
Defina formalmente um TAD.
Qual o papel do
.h?
-
LIFO e aplicações reais
Explique LIFO e aplique em:
- Navegadores (histórico)
- Editores (undo/redo)
- Chamadas de função (recursão)
-
Ponteiros e vetores
Explique:
Como o compilador calcula o endereço?
-
Complexidade (Pior Caso)
Qual o custo da busca em lista não ordenada?
Por que usamos pior caso?
-
Encapsulamento na prática
Por que
main.cnão deve acessarl->ultimo?
-
Alocação dinâmica vs estática
Compare:
- Flexibilidade
- Fragmentação
- Comparação de Pilhas
| Critério | Estática (Vetor) | Dinâmica (Encadeada) |
|---|---|---|
| Overhead | Baixo | Alto |
| Cache | Alto | Baixo |
| Crescimento | Fixo | Dinâmico |
| Limite | Compilação | RAM |
-
Operador
>Explique por que:
-
Rastreamento de memória
Dado:
Simule:
Desenhe a tabela de memória
4. 💻 Parte II — Implementação Prática (15 Questões)¶
Aqui começa o nível engenharia real: ponteiros mal usados = bugs graves.
Exercícios¶
- Struct + Ponteiro
- Crie
struct Ponto - Função que altera via ponteiro
- Crie
- Alocação segura
- Criar vetor dinâmico
- Verificar erro
- Inicializar com zero
-
Refatoração
-
Remover globais:
-
Criar TAD
-
- Push com verificação
- Implementar
empilha - Tratar overflow
- Implementar
- Pop em lista encadeada
- Remover nó
- Liberar memória
- Inicialização segura
Lista* criaLista()- Retornar
NULLse falhar
- Busca sequencial
- Implementar
- Justificar O(n)
- Inserção com deslocamento
- Lista estática
- Validar posição
- Liberação de lista
- Liberar todos os nós
- Evitar perda de referência
- realloc seguro
- Dobrar tamanho
- Usar ponteiro temporário
- Busca por posição
- Vetor → O(1)
- Lista → O(n)
- Inversão com pilha
- Usar estrutura auxiliar
- Lista circular
-
Último aponta para primeiro
O
while (atual != NULL)funciona?
- Reuso de funções (DRY)
-
removeValorusando outras funçõesQual a complexidade total?
-
Bug de precedência
Corrigir:
Explique o erro
5. 📊 Análise de Complexidade¶
Comparativo¶
| Operação | Vetor | Lista Encadeada |
|---|---|---|
| Acesso | O(1) | O(n) |
| Inserção início | O(n) | O(1) |
| Inserção fim | O(1) | O(n)* |
| Localidade | Alta | Baixa |
| - Pode ser O(1) com ponteiro para o último |
6. 🧪 Questão Bônus (Projeto)¶
Desenvolva uma pilha com:
- push
- pop
- findMax() → O(1)
Dica:
Use uma pilha auxiliar de máximos
7. ✅ Checklist Final¶
Antes de entregar:
- [ ] Todo
malloctemfree - [ ] Verificou
NULL - [ ] Estrutura validada antes de uso
- [ ] Sem variáveis globais
- [ ] Encapsulamento respeitado
⚠️ Regra de Ouro¶
Variáveis globais são proibidas.
Controle de memória e escopo é responsabilidade do programador.