C++: Prática: Ponteiros e Referências Abrangente

Última atualização: 2026-08-26

Aulas anteriores cobriram ponteiros e referências separadamente, mas em programas reais eles são usados juntos.

Nesta aula, vamos praticar fazer ponteiros e referências trabalharem juntos através de vários exemplos abrangentes.


1. Exemplo 1: Inversão de String Usando Ponteiros*

▶ Exemplo 1: Inversão de String (Dificuldade ⭐⭐)

CPP
#include <iostream>
#include <cstring>

void reverseString(char* str) {
	int len = std::strlen(str);
	char* left = str;
	char* right = str + len - 1;
	
	while (left < right) {
		// Trocar caracteres apontados por left e right
		char temp = *left;
		*left = *right;
		*right = temp;
		
		left++;
		right--;
	}
}

int main() {
	char str[] = "Hello, World!";
	std::cout << "Before reversal: " << str << std::endl;
	
	reverseString(str);
	
	std::cout << "After reversal: " << str << std::endl;
	
	return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Before reversal:
After reversal:


2. Exemplo 2: Array Dinâmico de Structs*

▶ Exemplo 2: Alocando Dinamicamente Array de Alunos (Dificuldade ⭐⭐⭐)

CPP
#include <iostream>
#include <string>

struct Student {
	std::string name;
	int age;
	double score;
};

int main() {
	int n;
	std::cout << "Enter number of students: ";
	std::cin >> n;
	
	// Alocar dinamicamente array de Student
	Student* students = new Student[n];
	
	// Inserir informações dos alunos
	for (int i = 0; i < n; i++) {
		std::cout << "Enter name for student " << i + 1 << ": ";
		std::cin.ignore();
		std::getline(std::cin, students[i].name);
		
		std::cout << "Enter age: ";
		std::cin >> students[i].age;
		
		std::cout << "Enter score: ";
		std::cin >> students[i].score;
	}
	
	// Exibir todas as informações dos alunos
	std::cout << "\n========== Student List ==========\n";
	for (int i = 0; i < n; i++) {
		std::cout << i + 1 << ". " << students[i].name 
			<< ", Age: " << students[i].age 
			<< ", Score: " << students[i].score << std::endl;
	}
	
	// Liberar memória
	delete[] students;
	
	return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Enter number of students:
Enter name for student :
Enter age:
Enter score:

========== Student List ==========

. 


3. Exemplo 3: Noções Básicas de Lista Ligada (Opcional)*

(1) 3.1 O Que É uma Lista Ligada?

Uma lista ligada é uma estrutura de dados dinâmica — cada elemento (nó) armazena dados e um ponteiro para o próximo nó.

Analogia do Mundo Real Equivalente na Programação
Caça ao tesouro (cada pista aponta para a localização da próxima) Lista ligada

▶ Exemplo 3: Lista Ligada Simples (Dificuldade ⭐⭐⭐)

CPP
#include <iostream>

struct Node {
	int data;
	Node* next;
};

int main() {
	// Criar nós
	Node* head = new Node{1, nullptr};
	Node* second = new Node{2, nullptr};
	Node* third = new Node{3, nullptr};
	
	// Conectar nós
	head->next = second;
	second->next = third;
	
	// Percorrer lista ligada
	Node* current = head;
	while (current != nullptr) {
		std::cout << current->data << " ";
		current = current->next;
	}
	std::cout << std::endl;
	
	// Liberar memória
	delete head;
	delete second;
	delete third;
	
	return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
 

💡 Dica: Listas ligadas são um tópico importante em estruturas de dados — esta é apenas uma breve introdução. Você aprenderá mais estruturas de dados depois.



4. Exercício Prático: Agenda (Versão com Memória Dinâmica)*

▶ Exemplo 4: Agenda Dinâmica (Dificuldade ⭐⭐⭐)

CPP
#include <iostream>
#include <string>
#include <cstring>

struct Contact {
	char name[50];
	char phone[20];
	Contact* next; // Ponteiro da lista ligada
};

Contact* head = nullptr; // Ponteiro cabeça da lista ligada

void addContact(const std::string& name, const std::string& phone) {
	Contact* newContact = new Contact;
	std::strcpy(newContact->name, name.c_str());
	std::strcpy(newContact->phone, phone.c_str());
	newContact->next = head; // Novo nó aponta para a cabeça original
	head = newContact; // Atualizar cabeça
}

void printContacts() {
	if (head == nullptr) {
		std::cout << "Address book is empty!" << std::endl;
		return;
	}
	
	std::cout << "\n========== Address Book ==========\n";
	Contact* current = head;
	int index = 1;
	while (current != nullptr) {
		std::cout << index << ". " << current->name 
			<< " - " << current->phone << std::endl;
		current = current->next;
		index++;
	}
}

int main() {
	addContact("MOTO", "13800138000");
	addContact("Alice", "13900139000");
	addContact("Bob", "13700137000");
	
	printContacts();
	
	// Liberar memória (opcional)
	// ...
	
	return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Address book is empty!

========== Address Book ==========

. 

❓ Perguntas Frequentes

P: Quando devo usar ponteiros vs referências? R:> - Se um parâmetro pode ser modificado e precisa representar "nada" (ex.: falha na busca) → ponteiro (nullptr) > - Se um parâmetro pode ser modificado mas sempre tem um valor → referência > - Se um parâmetro não precisa ser modificado → referência const (recomendado) > - Se alocação dinâmica de memória é necessária → ponteiro (new) P: Por que listas ligadas são melhores que arrays? R:> - Array: tamanho fixo, inserir/excluir requer deslocar todos os elementos subsequentes (lento) > - Lista ligada: tamanho dinâmico, inserir/excluir requer apenas mudar ponteiros (rápido)

Mas listas ligadas também têm desvantagens: sem acesso aleatório (para encontrar o i-ésimo elemento, você deve percorrer desde o início).

P: Como evitar vazamentos de memória? R:> 1. Garantir que new e delete estejam emparelhados > 2. Definir ponteiro para nullptr imediatamente após liberar > 3. Usar smart pointers (std::unique_ptr, std::shared_ptr, cobertos mais tarde)


P: O que é mais importante na prática com ponteiros? R: Entenda os conceitos centrais primeiro, depois solidifique com exemplos práticos.

📖 Resumo


📝 Exercícios

  1. Básico (Dificuldade ⭐): Escreva uma função void swap(int* a, int* b) que troque os valores de duas variáveis usando ponteiros.

  2. Intermediário (Dificuldade ⭐⭐): Escreva um programa que aloque dinamicamente um array de int, permita que o usuário insira o tamanho e conteúdo do array, depois inverta o array e exiba-o.

  3. Desafio (Dificuldade ⭐⭐⭐): Estenda o programa "Agenda Dinâmica":

    1. Adicione um recurso de "excluir contato"
    2. Adicione um recurso de "buscar contato"
    3. Libere toda a memória alocada dinamicamente quando o programa terminar

5. 🚀 Próximos Passos*

Parabéns! Você completou todas as aulas da Fase 4 (Ponteiros e Referências). A seguir, entramos na Fase 5 (Programação Orientada a Objetos) — aprendendo o recurso mais central do C++, entendendo classes, objetos, herança e polimorfismo!

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%