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¶
1. Passagem por valor vs referência¶
Explique por que funções como empilha(int x, Pilha *p) usam ponteiros.
O que aconteceria se a pilha fosse passada por valor?
2. Stack vs Heap¶
Diferencie:
- Stack (automática)
- Heap (dinâmica)
Quem gerencia cada uma?
Por que retornar variável local é perigoso?
3. Tipo Abstrato de Dado (TAD)¶
Defina formalmente um TAD.
Qual o papel do .h?
4. LIFO e aplicações reais¶
Explique LIFO e aplique em:
- Navegadores (histórico)
- Editores (undo/redo)
- Chamadas de função (recursão)
5. Ponteiros e vetores¶
Explique:
Como o compilador calcula o endereço?
6. Complexidade (Pior Caso)¶
Qual o custo da busca em lista não ordenada?
Por que usamos pior caso?
7. Encapsulamento na prática¶
Por que main.c não deve acessar l->ultimo?
8. Alocação dinâmica vs estática¶
Compare:
- Flexibilidade
- Fragmentação
9. Comparação de Pilhas¶
| Critério | Estática (Vetor) | Dinâmica (Encadeada) |
|---|---|---|
| Overhead | Baixo | Alto |
| Cache | Alto | Baixo |
| Crescimento | Fixo | Dinâmico |
| Limite | Capacidade fixa (definida na criação) | RAM |
Explique cada linha da tabela e diga em que situação você escolheria cada implementação.
10. Operador ->¶
Explique por que:
11. 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¶
1. Struct + Ponteiro¶
- Crie
struct Ponto - Função que altera via ponteiro
2. Alocação segura¶
- Criar vetor dinâmico
- Verificar erro
- Inicializar com zero
3. Refatoração¶
-
Remover globais:
-
Criar TAD
4. Push com verificação¶
- Implementar
empilha - Tratar overflow
5. Pop em lista encadeada¶
- Remover nó
- Liberar memória
6. Inicialização segura¶
Lista* criaLista()- Retornar
NULLse falhar
7. Busca sequencial¶
- Implementar
- Justificar O(n)
8. Inserção com deslocamento¶
- Lista estática
- Validar posição
9. Liberação de lista¶
- Liberar todos os nós
- Evitar perda de referência
10. realloc seguro¶
- Dobrar tamanho
- Usar ponteiro temporário
11. Busca por posição¶
Implemente buscaPos nas duas versões e justifique as complexidades:
- Vetor → O(1)
- Lista → O(n)
12. Inversão com pilha¶
- Usar estrutura auxiliar
13. Lista circular¶
- Último aponta para primeiro
O while (atual != NULL) funciona?
14. Reuso de funções (DRY)¶
removeValorusando outras funções
Qual a complexidade total?
15. Bug de precedência (prática)¶
Corrija o código abaixo e teste-o compilando:
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 nas soluções deste caderno.
Controle de memória e escopo é responsabilidade do programador.