Giao diện
💪 Exercises — Bài tập thực hành
Lý thuyết không đủ — bạn cần code thực tế. Hoàn thành 3 bài tập dưới đây để củng cố kiến thức về Memory, Pointers, và I/O.
🏆 Challenge 1: Swap Two Variables Using Pointers
Yêu cầu
Viết hàm swapPointers nhận vào hai con trỏ và hoán đổi giá trị tại hai địa chỉ đó.
cpp
#include <iostream>
void swapPointers(int* a, int* b) {
// TODO: Implement this function
}
int main() {
int x = 10, y = 20;
std::cout << "Before swap: x = " << x << ", y = " << y << std::endl;
swapPointers(&x, &y);
std::cout << "After swap: x = " << x << ", y = " << y << std::endl;
// Expected: x = 20, y = 10
return 0;
}💡 Gợi ý
- Bạn cần dereference pointer để truy cập giá trị
- Dùng biến tạm để lưu giá trị trước khi ghi đè
✅ Lời giải
cpp
#include <iostream>
void swapPointers(int* a, int* b) {
int temp = *a; // Lưu giá trị tại địa chỉ a
*a = *b; // Gán giá trị tại b cho vị trí a
*b = temp; // Gán temp cho vị trí b
}
int main() {
int x = 10, y = 20;
std::cout << "Before swap: x = " << x << ", y = " << y << std::endl;
swapPointers(&x, &y);
std::cout << "After swap: x = " << x << ", y = " << y << std::endl;
return 0;
}Output:
Before swap: x = 10, y = 20
After swap: x = 20, y = 10Bonus — Version với References (cleaner):
cpp
void swapRef(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
// Usage: swapRef(x, y); // Không cần &🏆 Challenge 2: Array Traversal Using Pointer Arithmetic
Yêu cầu
Cho một mảng số nguyên, in tất cả phần tử sử dụng pointer arithmetic (không dùng array indexing arr[i]).
cpp
#include <iostream>
void printArrayWithPointer(int* arr, int size) {
// TODO: Dùng pointer arithmetic để in từng phần tử
// KHÔNG được dùng arr[i]!
}
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int size = sizeof(numbers) / sizeof(numbers[0]);
std::cout << "Array elements: ";
printArrayWithPointer(numbers, size);
std::cout << std::endl;
// Expected output: 10 20 30 40 50
return 0;
}💡 Gợi ý
*(arr + i)tương đươngarr[i]- Hoặc dùng
ptr++để di chuyển pointer qua từng phần tử
✅ Lời giải
*Cách 1: Dùng (arr + i)
cpp
#include <iostream>
void printArrayWithPointer(int* arr, int size) {
for (int i = 0; i < size; ++i) {
std::cout << *(arr + i) << " ";
}
}
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int size = sizeof(numbers) / sizeof(numbers[0]);
std::cout << "Array elements: ";
printArrayWithPointer(numbers, size);
std::cout << std::endl;
return 0;
}Cách 2: Dùng pointer increment
cpp
void printArrayWithPointer(int* arr, int size) {
int* end = arr + size; // Pointer đến "past-the-end"
for (int* ptr = arr; ptr != end; ++ptr) {
std::cout << *ptr << " ";
}
}Output:
Array elements: 10 20 30 40 50🏆 Challenge 3: Memory Inspector
Yêu cầu
Viết chương trình tạo các biến thuộc các vùng nhớ khác nhau (Stack, Heap, Global) và in ra địa chỉ của chúng. Quan sát pattern địa chỉ.
cpp
#include <iostream>
// TODO: Khai báo biến global
int main() {
// TODO: Khai báo biến local (stack)
// TODO: Cấp phát biến trên heap
std::cout << "=== Memory Inspector ===" << std::endl;
// TODO: In địa chỉ của từng biến
// Format: "Variable name (segment): address"
// TODO: Giải phóng memory
return 0;
}Expected Output Pattern:
=== Memory Inspector ===
globalVar (DATA/BSS): 0x404xxx (low address)
heapVar (HEAP): 0x55xxxx (medium address)
localVar (STACK): 0x7fffxx (high address)💡 Gợi ý
- Global variables: khai báo ngoài main()
- Stack: biến local trong main()
- Heap: dùng
new - Dùng
&variableđể lấy địa chỉ
✅ Lời giải
cpp
#include <iostream>
#include <iomanip>
// Global variable — .DATA segment (initialized)
int globalInit = 100;
// Global variable — .BSS segment (uninitialized → auto 0)
int globalUnInit;
int main() {
// Stack variable
int localVar = 42;
// Heap variable
int* heapVar = new int(200);
std::cout << "=== Memory Inspector ===" << std::endl;
std::cout << std::left;
std::cout << std::setw(25) << "globalInit (DATA):"
<< &globalInit << std::endl;
std::cout << std::setw(25) << "globalUnInit (BSS):"
<< &globalUnInit << std::endl;
std::cout << std::setw(25) << "heapVar content (HEAP):"
<< heapVar << std::endl;
std::cout << std::setw(25) << "localVar (STACK):"
<< &localVar << std::endl;
std::cout << std::setw(25) << "heapVar pointer (STACK):"
<< &heapVar << std::endl;
// Analysis
std::cout << "\n=== Analysis ===" << std::endl;
std::cout << "Observe: DATA/BSS addresses are LOWER than HEAP" << std::endl;
std::cout << " HEAP addresses are LOWER than STACK" << std::endl;
std::cout << "Memory layout: [TEXT | DATA | BSS | HEAP ↑ ... ↓ STACK]" << std::endl;
// Cleanup
delete heapVar;
heapVar = nullptr;
return 0;
}Sample Output (addresses vary):
=== Memory Inspector ===
globalInit (DATA): 0x404018
globalUnInit (BSS): 0x404020
heapVar content (HEAP): 0x556b8c4f0eb0
localVar (STACK): 0x7ffd1a3b3a44
heapVar pointer (STACK): 0x7ffd1a3b3a48
=== Analysis ===
Observe: DATA/BSS addresses are LOWER than HEAP
HEAP addresses are LOWER than STACK
Memory layout: [TEXT | DATA | BSS | HEAP ↑ ... ↓ STACK]🎯 Bonus Challenge: Dynamic Array Sum
Yêu cầu (Nâng cao)
Viết chương trình:
- Hỏi user số lượng phần tử
- Cấp phát mảng động trên heap
- Nhập từng phần tử
- Tính tổng bằng pointer arithmetic
- Giải phóng memory đúng cách
✅ Lời giải
cpp
#include <iostream>
int main() {
int size;
std::cout << "Nhập số lượng phần tử: ";
std::cin >> size;
if (size <= 0) {
std::cerr << "Size phải > 0!" << std::endl;
return 1;
}
// Cấp phát heap
int* arr = new int[size];
// Nhập phần tử
std::cout << "Nhập " << size << " số:\n";
for (int i = 0; i < size; ++i) {
std::cout << "arr[" << i << "] = ";
std::cin >> *(arr + i); // Pointer arithmetic
}
// Tính tổng bằng pointer
int sum = 0;
int* end = arr + size;
for (int* ptr = arr; ptr != end; ++ptr) {
sum += *ptr;
}
std::cout << "Tổng: " << sum << std::endl;
// ⚠️ CRITICAL: Giải phóng memory
delete[] arr; // delete[] cho arrays!
arr = nullptr;
return 0;
}Output:
Nhập số lượng phần tử: 4
Nhập 4 số:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
Tổng: 100📚 Đánh giá kết quả
| Exercise | Concepts Covered |
|---|---|
| Challenge 1 | Pointers, Dereference, Pass by Pointer |
| Challenge 2 | Pointer Arithmetic, Arrays |
| Challenge 3 | Memory Layout, Stack/Heap/Data |
| Bonus | Dynamic Allocation, Memory Management |
➡️ Tiếp theo
🎉 Chúc mừng! Bạn đã hoàn thành Part 1: C++ Basics.
Quay lại C++ Engineering để tiếp tục với các modules khác.