Giao diện
🔀 Control Flow — Điều khiển luồng
Control flow quyết định thứ tự thực thi của code. Hiểu rõ if/else, switch, và loops là nền tảng để viết logic phức tạp.
if / else — Cơ bản
cpp
#include <iostream>
int main() {
int score = 85;
if (score >= 90) {
std::cout << "Grade: A" << std::endl;
} else if (score >= 80) {
std::cout << "Grade: B" << std::endl;
} else if (score >= 70) {
std::cout << "Grade: C" << std::endl;
} else {
std::cout << "Grade: F" << std::endl;
}
return 0;
}if với Initializer (C++17)
C++17 cho phép khai báo biến trong điều kiện if:
cpp
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> ages = {{"Alice", 25}, {"Bob", 30}};
// C++17: if với initializer
if (auto it = ages.find("Alice"); it != ages.end()) {
std::cout << "Found: " << it->first << " = " << it->second << std::endl;
} else {
std::cout << "Not found" << std::endl;
}
// 'it' không tồn tại ngoài scope này — clean!
return 0;
}📌 Best Practice
Dùng if với initializer khi biến chỉ cần tồn tại trong scope của if/else. Giúp code clean hơn và tránh biến thừa.
switch / case
cpp
#include <iostream>
int main() {
int day = 3;
switch (day) {
case 1:
std::cout << "Monday" << std::endl;
break;
case 2:
std::cout << "Tuesday" << std::endl;
break;
case 3:
std::cout << "Wednesday" << std::endl;
break;
case 4:
case 5:
std::cout << "Thursday or Friday" << std::endl;
break;
default:
std::cout << "Weekend" << std::endl;
}
return 0;
}[[fallthrough]] Attribute (C++17)
Khi cố ý không dùng break, dùng [[fallthrough]] để thông báo cho compiler (và người đọc):
cpp
#include <iostream>
int main() {
int level = 3;
std::cout << "Rewards for level " << level << ":" << std::endl;
switch (level) {
case 3:
std::cout << " - Legendary Sword" << std::endl;
[[fallthrough]]; // C++17: Cố ý fall-through
case 2:
std::cout << " - Epic Armor" << std::endl;
[[fallthrough]];
case 1:
std::cout << " - Basic Potion" << std::endl;
break;
default:
std::cout << " - Nothing" << std::endl;
}
return 0;
}Output (level = 3):
Rewards for level 3:
- Legendary Sword
- Epic Armor
- Basic Potion⚠️ Không có [[fallthrough]] → Compiler Warning
Nếu bạn quên break mà không có [[fallthrough]], nhiều compilers sẽ cảnh báo:
warning: unannotated fall-through between switch labelsfor Loop — Vòng lặp cơ bản
C-style for loop
cpp
#include <iostream>
int main() {
// Cú pháp: for (init; condition; increment)
for (int i = 0; i < 5; ++i) {
std::cout << i << " ";
}
std::cout << std::endl;
// Output: 0 1 2 3 4
// Đếm ngược
for (int i = 5; i > 0; --i) {
std::cout << i << " ";
}
std::cout << std::endl;
// Output: 5 4 3 2 1
return 0;
}++i vs i++
cpp
// Trong vòng lặp, dùng ++i (pre-increment) thay vì i++ (post-increment)
// Lý do: ++i không tạo bản sao tạm thời → Hiệu quả hơn
for (int i = 0; i < n; ++i) { ... } // ✅ Preferred
for (int i = 0; i < n; i++) { ... } // ❌ Tạo bản sao không cần thiếtwhile và do-while
while — Kiểm tra trước
cpp
#include <iostream>
int main() {
int count = 0;
while (count < 3) {
std::cout << "Count: " << count << std::endl;
++count;
}
return 0;
}do-while — Thực hiện ít nhất 1 lần
cpp
#include <iostream>
int main() {
int input;
do {
std::cout << "Nhập số từ 1-10: ";
std::cin >> input;
} while (input < 1 || input > 10);
std::cout << "Bạn nhập: " << input << std::endl;
return 0;
}📌 Khi nào dùng do-while?
- Input validation: Cần nhập ít nhất 1 lần
- Menu loops: Hiển thị menu ít nhất 1 lần trước khi check điều kiện thoát
break và continue
cpp
#include <iostream>
int main() {
// break: Thoát khỏi vòng lặp
for (int i = 0; i < 10; ++i) {
if (i == 5) {
break; // Dừng hoàn toàn
}
std::cout << i << " ";
}
std::cout << std::endl; // Output: 0 1 2 3 4
// continue: Bỏ qua iteration hiện tại
for (int i = 0; i < 10; ++i) {
if (i % 2 == 0) {
continue; // Bỏ qua số chẵn
}
std::cout << i << " ";
}
std::cout << std::endl; // Output: 1 3 5 7 9
return 0;
}Nested Loops và Labels
cpp
#include <iostream>
int main() {
// Tìm cặp (i, j) đầu tiên có tổng = 5
bool found = false;
for (int i = 0; i < 5 && !found; ++i) {
for (int j = 0; j < 5; ++j) {
if (i + j == 5) {
std::cout << "Found: i=" << i << ", j=" << j << std::endl;
found = true;
break; // Chỉ thoát inner loop
}
}
}
return 0;
}💡 C++ không có labeled break
Không giống Java/JavaScript, C++ không có break label;. Thay vào đó:
- Dùng flag variable (
found) - Dùng
goto(không khuyến khích) - Extract thành function và dùng
return
Infinite Loops
cpp
#include <iostream>
int main() {
// Cách 1: for(;;)
// for (;;) {
// // infinite loop
// }
// Cách 2: while(true)
// while (true) {
// // infinite loop
// }
// Ví dụ: Server main loop
int requestCount = 0;
while (true) {
std::cout << "Processing request " << ++requestCount << std::endl;
if (requestCount >= 3) {
std::cout << "Shutting down..." << std::endl;
break;
}
}
return 0;
}🐛 Bug Hunt Challenge
🐛 Bug Hunt
Đoạn code sau có bug gì?
cpp
#include <iostream>
int main() {
int i = 0;
while (i < 10);
{
std::cout << i << std::endl;
++i;
}
return 0;
}💡 Gợi ý
Chú ý dấu ; sau while (i < 10).
🔍 Giải thích
Bug: Dấu ; sau while tạo một empty loop body!
cpp
while (i < 10); // Loop body là empty statement!Vòng while chạy mãi mãi (i luôn = 0 < 10) vì block {} phía sau không phải là body của while.
Fix:
cpp
while (i < 10) { // Bỏ dấu ;
std::cout << i << std::endl;
++i;
}📚 Tổng kết
| Concept | Usage |
|---|---|
if with initializer | C++17 — clean scope cho biến tạm |
[[fallthrough]] | C++17 — đánh dấu fall-through có chủ đích |
++i vs i++ | Prefer ++i trong loops |
break | Thoát hoàn toàn khỏi loop |
continue | Bỏ qua iteration hiện tại |
do-while | Chạy ít nhất 1 lần |
➡️ Tiếp theo
Tiếp theo: Modern Loops — Range-based for loop và tại sao nó tốt hơn C-style loops.