# Vòng lặp trong [C++]
###### Credits: 10CtinTDN 25_28
Trong bài viết này, chúng ta sẽ tìm hiểu cơ bản 2 vòng lặp `for` và `while` trong ngôn ngữ C++ cùng các bài toán cơ bản trong việc làm quen với dạng vòng lặp này. 💻
## 1. Vòng lặp `FOR`
###### *Nguồn: VNOI Wiki, 28Tech và bộ não của 10CTin25_28*
:::info
**Nội dung:** 📖
* Vòng lặp `for`
* Cách hoạt động ⚙️
* Ví dụ áp dụng & thực hành
:::
Định nghĩa vòng lặp: giúp bạn thực hiện câu lệnh nhiều lần theo ý bạn muốn (có điều kiện nhất định). Ví dụ muốn in ra dòng chữ `"Hello CTin"` 1000 lần trên 1000 dòng thì thay vì viết 1000 câu lệnh `cout` chỉ cần viết vòng lặp lặp từ `1 -> 1000`
- Vòng lặp for là vòng lặp *biết trước số lần lặp* 🔢
---
### **1.1 Cú pháp:**
Cú pháp của câu lệnh for là dòng `for()` với các khởi tạo một biến có một số lần lặp định trước.
```cpp!
for (Câu_lệnh_khởi_tạo ; Điều_kiện_lặp; Câu_lệnh_cập_nhật){
//code (hành động thực hiện trong vòng lặp được lặp)
}
```
### **1.2 Cách hoạt động:**
1. Câu lệnh khởi tạo được thực hiện 1 lần duy nhất khi bắt đầu vào vòng lặp
2. Sau đó điều kiện lặp được kiểm tra, nếu đúng thì sẽ tiến thành thực hiện các câu lệnh trong for, sai sẽ không thực hiện và kết thúc vòng lặp
3. Sau khi các câu lệnh trong vòng lặp được thực hiện xong thì tới phần câu lệnh cập nhật được thực thi
4. Câu lệnh cập nhật được thực hiện xong sẽ tiếp tục kiểm tra điều kiện lặp và nếu đúng tiếp tục thực hiện code trong vòng lặp, sai sẽ kết thúc vòng lặp
**Ví dụ 1: Nhập vào số `n`, in ra chuỗi `"Hello Ctin"` n lần trên mỗi dòng** 🔢
```cpp=
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
for (int i = 1; i<=n;i++) { //chạy lặp từ 1 => n
cout<<"Hello Ctin"<<endl; // in ra n lần
}
return 0;
}
```
:::warning
**Input:** 4
:::
:::success
**Output:**
Hello Ctin
Hello Ctin
Hello Ctin
Hello Ctin
:::
:::spoiler **Giải thích:** ❓
- Vòng lặp biến i được khởi tạo bắt đầu `i=1`, sau đó kiểm tra điều kiện `i<=4` se có giá trị đúng (tức điều kiện còn thỏa man) nên in ra chuỗi.
- Biến i sau khi được thực hiện câu lệnh thì sẽ tăng lên 1 `i++` (i = i+1) và sẽ có giá trị 2 => vẫn còn hợp điều kiện nên sẽ thực hiện và tổng lần thực hiện chính là 4 lần cho tới khi i = 5 (sau khi i++ lần thứ 4). Khi đó điều kiện không còn hợp lệ nên out khỏi vòng lặp (kết thúc).
:::
---
### 1.3 Một số vòng lặp for đặc biệt 😖
- Vòng lặp thường có 3 phần: **khởi tạo, điều kiện và cập nhật** nhưng vòng lặp vẫn có thể hoạt động khi thiếu những phần này tùy vào cách sử dụng lặp.
**Ví dụ :** For không có điều kiện lặp *(lặp vô tận)*
```cpp!
#include <iostream>
using namespace std;
int main(){
for(int i = 1; ;i++){
cout << "Ctin" << endl;
}
return 0;
}
```
- Tương tự có thể khuyết cập nhật và điều kiện để lặp vô tận hoặc khuyết hết (`for(; ;)`) để lặp vô tận và tùy vào điều kiện của đề bài mà sử dụng vòng lặp đặc biệt. 🤖
- Ngoài vòng lặp khuyết ra còn có vòng lặp quét qua tất cả phần tử trong một cấu trúc dữ liệu, thường dùng để lấy các phần tử từ mảng, vector,... ra để sử dụng với cú pháp `for((kiểu dữ liệu) biến : cấu trúc dữ liệu)`
```cpp!
for (int x : a) { //mỗi lần lặp là duyệt qua mảng lấy ra giá trị x trong mảng a[]
//code:
cout<<"phần tử của mảng a "<<x<<endl;
}
```
---
### 1.4 Thực hành
Một số bài toán sử dụng FOR:

Hoặc tham khảo các bài tập từ *online judge*: 😎
- https://marisaoj.com/module/2\
---
## 2. Vòng lặp `WHILE`
:::info
**Nội dung:** 📖
* Vòng lặp `while`
* Cách hoạt động ⚙️
* Ví dụ áp dụng & thực hành
:::
Vòng lặp `while` là vòng lặp thông dụng thứ 2 sau vòng lặp for, cú pháp của while có phần dễ hiểu hơn so với vòng lặp for.
- Vòng lặp `while` thường được gọi là **lặp không biết trước số lần lặp**.
---
### 2.1 Cú pháp 💻
Cú pháp của `while` là
`while ()` và ở trong dấu ngoặc là điều kiện khi vòng lặp vẫn còn trong điều kiện thì chạy khi điều kiện không còn đúng nữa thì dừng điều kiện. 🤖
```cpp=
while (true //điều kiện) {
//code
cout<<"vòng lặp while"<<endl;
}
```
---
### 2.2 Cách hoạt động ⚒️
1. Vòng lặp while vào kiểm tra 1 hoặc nhiều điều kiện (conditions) bên trong ngoặc tròn `()`
2. Nếu điều kiện không thõa mãn, vòng lặp sẽ không thực hiện code mà kết thúc ngay ❌
3. Nếu điều kiện thõa mãn, vòng lặp sẽ tiến hành thực hiện code bên trong vòng lặp, sau khi thực hiện các câu lệnh code vòng lặp while sẽ quay lại kiểm tra điều kiện✅
4. Bước 3 được lặp đi lặp lại cho tới khi điều kiện trong while không thõa mãn thì vòng lặp kết thúc, nếu điều kiện này luôn luôn thõa mãn thì vòng while sẽ không dừng lại
**Ví dụ:** In ra các số từ `1 -> số nguyên n` dùng vòng lặp `while`:
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n; // Nhập n
int i = 1;
while(i <= n){
cout << i << " ";
++i; // Khi điều kiện vẫn còn thõa mãn thì thực hiện hành động code (cout và cộng i lên 1 đơn vị)
}
return 0;
}
```
:::warning
**Input:** 4
:::
:::success
**Output:** 1 2 3 4
:::
:::spoiler **Giải thích:** ❓
- Vòng lặp while kiểm tra i <= n tương đương 1 <= 4 có giá trị đúng, câu lệnh cout in ra 1, sau đó ++i, giá trị của i lên 2
- Vòng lặp quay lại kiểm tra i <= n tương đương 2 <= 4 có giá trị đúng, câu lệnh cout in ra 2, sau đó ++i, giá trị của i lên 3
- Vòng lặp quay lại kiểm tra i <= n tương đương 3 <= 4 có giá trị đúng, câu lệnh cout in ra 3, sau đó ++i, giá trị của i lên 4
- Vòng lặp quay lại kiểm tra i <= n tương đương 4 <= 4 có giá trị đúng, câu lệnh cout in ra 4, sau đó ++i, giá trị của i lên 5
- Vòng lặp quay lại kiểm tra i <= n tương đương 5 <= 4 có giá trị sai nên vòng lặp kết thúc
:::
###### (xin lỗi người đọc nếu quá dài mọi người có thể skip phần này nếu thấy có thể).
### 2.3 Vòng lặp do-while
Nếu đã hiểu rõ cách hoạt động của vòng lặp while thì do while cũng gần như tương tự với cú pháp có khác một chút
**Cú pháp:** 📝
```cpp!
do {
//code
} while (condition);
```
**Cách hoạt động:** ❓
1. Code trong thân vòng lặp (phần trong do) được thực hiện 1 lần trước rồi kiểm tra điều kiện lặp
2. Nếu điều kiện trong while không thõa thì dừng lặp
3. Nếu thõa mãn thì thân code được lặp lại
4. Bước 3 được lặp lại cho tới khi điều kiện không thõa => Nếu luôn thõa sẽ lặp vĩnh viễn trừ khi thoát lặp.
:::spoiler **VD1:** In ra các số từ `1 -> N` băng `do-while`
```cpp!
#include <iostream>
using namespace std;
int main(){
int i = 1;
int n; cin>>n;
do{
cout << i << ' ';
++i;
}while(i <= n);
return 0;
}
```
| *Input* | *Output* |
| -------- | -------- |
| 4 | 1 2 3 4 |
**Giải thích:**
- Vòng lặp thực hiện in ra i là 1, sau đó ++i thì i lên 2
- Vòng lặp kiểm tra điều kiện lặp : i <= n hay 2 <= 4 có giá trị đúng nên tiếp tục in ra i là 2, ++i thì i tăng lên 3
- Vòng lặp kiểm tra điều kiện lặp : i <= n hay 3 <= 4 có giá trị đúng nên tiếp tục in ra i là 3, ++i thì i tăng lên 4
- Vòng lặp kiểm tra điều kiện lặp : i <= n hay 4 <= 4 có giá trị đúng nên tiếp tục in ra i là 4, ++i thì i tăng lên 5
- Vòng lặp kiểm tra điều kiện lặp : i <= n hay 5 <= 4 có giá trị sai nên vòng lặp kết thúc. (*nguồn: 28Tech*)
:::
---
### 2.4 Thực hành 💻
Một số bài toán khi đã sử dụng thành thạo cả hai vòng lặp `for` và `while` thì khả năng sử dụng chúng tương đương nhau . Tuy nhiên vẫn có những bài toán dùng while sẽ tiện hơn for. ⭐

:::info
Có thể tìm hiểu thêm về các dạng bài dùng `while` và đọc blog nếu có ích (*https://blog.28tech.com.vn/cpp-vong-lap-while*)
:::
## **3. Một số tips sử dụng vòng lặp:** 💫
- Các vòng lặp `FOR` thường được sử dụng với cú pháp: `for (int i = a; i<=b; i+=val)` nên có thể dùng template `#define`:
```cpp!
#define FOR(i,a,b,val) for (int i = a; i<=b;i+=val)
```
- Sử dụng index (0...n-1) cũng tương tự với index (0...n) tùy vào kiểu dữ liệu và bài toán bạn cần sử dụng (mảng array thì nên dùng 1-based thay vì 0-based vì khả năng tư duy từ 1...n sẽ dễ hơn).
- Dùng `break` để thoát sớm (khi điều kiện hoặc đáp án đã có mà không cần lặp thêm để tìm) hoặc `continue` để bỏ qua lần lặp hiện tại để tới lần lặp tiếp theo. Ngoài ra còn có `goto` để thoát ra vòng lặp tới vị trí goto chỉ tới.
- Vòng lặp `while(1)`` hoặc `while(true)`` là luôn lặp do luôn đúng và chỉ có thể thoát vòng lặp bằng lệnh trả về hàm `return` hoặc thoát khỏi lặp như `break` và `goto`.
:::spoiler Bài học khác
**Trang khác của `TDN CTIN2528`:**
*[Introduction](/XT_7bEYUTwyxynr11yjW8w)
[Số Nguyên tố](/x7FMjRv7Qja0_wTyeD3_BQ)
[Mảng 1 chiều trong C++](/j9pu4Po6RICAcQbcYPInMA)*
:::