# I. Implementation Fundamentals
## I.1 - Statements
:::spoiler
Những câu lệnh
### I.1-a: Single Statement
Ex: `cout << "Hello World";`
### I.1-b: Compound Statement
```cpp
{
single statement;
single statement;
single statement;
...
}
```
### I.1-c: `if else`
```cpp
if(condition)
{
single statement;
single statement;
single statement;
...
}
else
{
single statement;
single statement;
single statement;
...
}
```
### I.1-d: `switch case`
```cpp
//n kết quả tương ứng với mỗi case
switch (n)
{
case <gắn đk vào>:
single command;
case <gắn đk vào>:
single command;
case <gắn đk vào>:
single command;
...
default:
single command;
}
//từng case có thể xem như các if và else if còn default là else(cứ cho là vậy đi)
```
`[[fallthrough]];` xảy ra khi ko có cách lệnh break trong các case, dẫn đến việc sai kết quả
### I.1-e: ternary operator
Giống if, nhưng rút gọn:
|None|IF|TERNARY OPERATOR|
|----|--|----------------|
|Code|`if (condition) {single command;...} else {single command;...}`|`condition ? consequent : alternative`|
|Explanation|`if (command)` -> điều kiện, `{single command;...}` là lệnh thực hiện khi thỏa mãn điều kiện|`condition ?` = `if (condition)`, `consequence` = câu lệnh thực hiện khi thỏa điều kiện, `alternative` = câu lệnh thực hiện khi không thỏa điều kiện|
### I.1-f: `while`
Lặp lại cho đến khi ...
```cpp
while (điều kiện khi vòng lặp này được phép chạy)
{
single statement;
single statement;
single statement;
...
}
```
### I.1-g: `do while`
Cũng giống như `while` nhưng `while` kiểm tra điều kiện trước khi thực hiện lệnh ở bên trong còn `do while` thì thực hiện lệnh trước khi kiểm tra điều kiện
```cpp
do
{
single statement;
single statement;
single statement;
...
}
while (điều kiện khi vòng lặp này được phép chạy)
```
### I.1-h: `for`
Cũng là vòng lặp nhưng xác định được số lần lặp.
```cpp
for (khởi tạo biến hay cái j ấy chả biết; điều kiện được phép lặp; thay đổi biến để chạy vòng lặp)
{
single statement;
single statement;
single statement;
...
}
```
### I.1-i: `range-for`
Giống `for` nhưng gọn hơn
```cpp
int a[9] = {1; 2; 3; 4; 5; 6; 7; 8; 9};
for (auto/int i : a)
{
single statement;
single statement;
single statement;
...
}
```
### I.1-j: `continue`
Nằm trong vòng lặp, dùng để bỏ qua lần lặp đó
EX:
```cpp
int a[9] = {1; 2; 3; 4; 5; 6; 7; 8; 9};
for (auto/int i : a)
{
if (i == 3) continue;
cout << i << " ";
}
```
**Output**
```
1 2 4 5 6 7 8 9
^
Mất số 3
```
### I.1-k: `break`
Nằm trong vòng lặp, dùng để thoát ra khỏi vòng lặp, lập tức dừng vòng lặp.
EX:
```cpp
int a[9] = {1; 2; 3; 4; 5; 6; 7; 8; 9};
for (auto/int i : a)
{
if (i == 6) break;
cout << i << " ";
}
```
**Output**
```
1 2 4 5
^
Dừng ngay sau số 5 vì khi i = 6 thì dừng ngay vòng lặp
```
### I.1-l: `goto`
Dùng để đi tới vị trí chúng ta muốn
EX:
```cpp
cout << "Hello";
cout << " we";
cout << " are";
goto lable;
cout << " not";
lable;
cout << " humans.";
```
**Output**
```
Hello we are humans.
^
Mất chữ 'not' vì lệnh goto đã bỏ qua dòng
lệnh thứ 5 là 'cout << "not";'
```
### I.1-m: `return ;` `return <expressions>;`
`return` thường được dùng để trả về một giá trị, đồng thời kết thúc một hành động nào đó và còn có thể dùng để fix bug.
```cpp
int main()
{
cout << "Hello world";
return 0;
// ngừng chương trình vì main trả về kiểu dữ liệu là int và 0 là một int
// vì vậy chương trình dừng hoàn toàn
}
```
```cpp
bool prime(int n)
{
if (n < 2) return false;
if (n == 2 || n == 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6)
{
if (n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
//các lệnh return trả về giá trị true và false vì prime trả về kiểu giá trị bool
//đồng thời ngừng ngay hàm kiểm tra số nguyên tố
//vì đã tìm được liệu rằng n có phải số nguyên tố hay không
}
```
### I.1-n: `while(true)` `for (;;)`
while true và for(;;) là vòng lặp vô tận.
```cpp
while (true) //lặp mãi mãi
{
single statement;
single statement;
single statement;
...
if (condition) break;
//khi điều kiện này đúng thì vòng lặp kết thúc
}
```
```cpp
for (;;) //lặp mãi mãi
{
single statement;
single statement;
single statement;
...
if (condition) break;
//khi điều kiện này đúng thì vòng lặp kết thúc
}
```
### I.1-o: `for (auto [u, v] : edges)` (C++17)
dùng để tách 2 biến trong pair thành 2 biến riêng biệt
```cpp
vector<pair<int, int>> edges =
{
{1, 2},
{2, 3},
{3, 4}
};
for (auto [u, v] : edges) cout << u << " " << v << "\n";
```
**Output**
```
1 2
2 3
3 4
In ra các giá trị được đi theo cặp
```
:::
## I.2 - Int Types
:::spoiler
Tất cả kiểu dữ liệu số
VD: int, long long, short,...
### I.2-a: `int` (>=2 byte)
Là kiểu số nguyên. Giới hạn: `2,147,483,647 → -2,147,483,648 (-2^31 → 2^31 - 1)`
```cpp
int a = 0;
int b = 2
cout << a + b;
```
**Output**
```
2
```
### I.2-b: `unsigned int`
Là kiểu số nguyên không âm. Giới hạn: `0 → 4,294,967,295 (0 → 2^32 - 1)`
```cpp
unsigned int a = 0;
unsigned int b = 2
cout << a + b;
```
**Output**
```
2
```
### I.2-c: `long long`
Là kiểu dữ liệu số nguyên lớn hơn int có thể âm. Giới hạn: `-9,223,372,036,854,775,808 → 9,223,372,036,854,775,807 (—10^18 → 10^18)`
```cpp
long long a = -99999999999999999;
long long b = 99999999999999999;
cout << a + b;
```
**Output**
```
0
```
### I.2-d: `unsigned long long`
Giống long long nhưng không âm. Giới hạn: `0 → 18,446,744,073,709,551,615 (0 → 2^64 - 1)`
```cpp
unsigned long long a = 111111111111111111;
unsigned long long b = 222222222222222222;
cout << a + b;
```
**Output**
```
333333333333333333
```
### I.2-e: `short`
Là số nguyên có thể âm, ngắn hơn int dùng để tính toán chính xác. Giới hạn: `-32,768 -> 32,767. (−2^15 → 2^15 − 1)`
```cpp
short a = 1212;
short b = 2121;
cout << a + b;
```
**Output**
```
3333
```
### I.2-f: `unsigned short`
Giống short nhưng không âm và số dương. Giới hạn: `0 → 65536 (0 → 2^16 − 1)`
```cpp
unsigned short a=6000;
cout<<a;
```
**Output**
```
6000
```
### I.2-g: `int8_t`
Kiểu số nguyên 8-bit có dấu. Giới hạn: `-128 → 127 (-2^7 → 2^7 − 1)`
```cpp
int8_t a = 100;
cout << (int)a;
```
**Output**
```
100
```
### I.2-h: `int16_t`
Kiểu số nguyên 16-bit có dấu. Giới hạn: `-32768 → 32767 (-2^15 → 2^15 − 1)`
```cpp
int16_t a = 12345;
cout << a;
```
**Output**
```
12345
```
### I.2-i: `int32_t`
Kiểu số nguyên 32-bit có dấu. Giới hạn: `-2147483648 → 2147483647 (-2^31 → 2^31 − 1)`
```cpp
int32_t a = 123456789;
cout << a;
```
**Output**
```
123456789
```
### I.2-j: `int64_t`
Kiểu số nguyên 64-bit có dấu. Giới hạn: `-9223372036854775808 → 9223372036854775807 (-2^63 → 2^63 − 1)`
```cpp
int64_t a = 123456789012345;
cout << a;
```
**Output**
```
123456789012345
```
### I.2-k: `uint8_t`
Kiểu số nguyên 8-bit không dấu. Giới hạn: `0 → 255 (0 → 2^8 − 1)`
```cpp
uint8_t a = 200;
cout << (int)a;
```
**Output**
```
200
```
### I.2-l: `uint16_t`
Kiểu số nguyên 16-bit không dấu. Giới hạn: `0 → 65535 (0 → 2^16 − 1)`
```cpp
uint16_t a = 50000;
cout << a;
```
**Output**
```
50000
```
### I.2-m: `uint32_t`
Kiểu số nguyên 32-bit không dấu. Giới hạn: `0 → 4294967295 (0 → 2^32 − 1)`
```cpp
uint32_t a = 3000000000;
cout << a;
```
**Output**
```
3000000000
```
### I.2-n: `uint64_t`
Kiểu số nguyên 64-bit không dấu. Giới hạn: `0 → 18446744073709551615 (0 → 2^64 − 1)`
```cpp
uint64_t a = 10000000000000000000ULL;
cout << a;
```
**Output**
```
10000000000000000000
```
### I.2-o: `size_t`
Kiểu số nguyên không dấu thường được dùng để biểu diễn kích thước bộ nhớ hoặc chỉ số mảng.
Giới hạn phụ thuộc vào hệ thống:
- Trên hệ thống 32-bit: `0 → 4294967295 (0 → 2^32 − 1)`
- Trên hệ thống 64-bit: `0 → 18446744073709551615 (0 → 2^64 − 1)`
```cpp
size_t a = 5000;
cout << a;
```
**Output**
```
5000
```
### I.2-p: `ssize_t` (C++20)
Giống `size_t` nhưng có dấu, cho phép lưu giá trị âm.
Giới hạn phụ thuộc vào hệ thống:
- Trên hệ thống 32-bit: `-2147483648 → 2147483647 (-2^31 → 2^31 − 1)`
- Trên hệ thống 64-bit: `-9223372036854775808 → 9223372036854775807 (-2^63 → 2^63 − 1)`
```cpp
ssize_t a = -5000;
cout << a;
```
**Output**
```
-5000
```
:::
## I.3 - Float Types
:::spoiler
### I.3-a: `float`
Là một dạng số thập phân với độ chính xác khoảng 6 - 7 chữ số thập phân. Giới hạn `1.175494351e−38 → 3.402823466e+38 (±(2^−126 → 2^128))`
```cpp
float a = 0.0001, b = 0.0001;
cout << a + b;
```
**Output**
```
0.0002
```
### I.3-b: `double`
Giống như `float` nhưng độ chính xác được nâng lên đến 15 - 16 chữ số thập phân. Giới hạn: `2.2250738585072014e−308 → 1.7976931348623157e+308 (±(2^−1022 → 2^1024))`
```cpp
double a = 1.5, b = 2.7;
cout << a + b;
```
**Output**
```
4.2
```
### I.3-c: `long double`
Tương tự như `double` nhưng độ chính xác được nâng lên tới 18 - 19 chữ số thập phân(tùy hệ thống). Giới hạn: `3.3621e−4932 → 1.1897e+4932 (±(2^−16382 → 2^16384))`
```cpp
long double x = 1.234567890123456789L, y = 2.345678901234567890L;
cout << x + y;
```
**Output**
```
3.58025
```
:::
## I.4 - Char & String Types
:::spoiler
Là kiểu dữ liệu kí tự.
Vd: char, string,...
### I.4-a: char
Là kiêu kí tự chỉ chứa 1 kí tự đơn chiếm 1 byte
```cpp
char a = A;
cout << a;
```
**Output**
```
A
```
### I.4-b: signed char
Lưu trữ 1 kí tự số nhỏ 1byte có thể âm và là kiểu char, thường dùng với số nhỏ nên tiết kiệm bộ nhớ
```cpp
signed char a = ''-1000';
cout << a;
```
**Output**
```
-1000
```
### I.4-c: unsigned char
Giống cái trên nhưng không âm
```cpp
unsigned char a='1000';
cout<<a;
```
**Output**
```
1000
```
### I.4-d: string
Là 1 mảng kí tự có giới hạn khoảng 2^64 tùy hệ thống.
```cpp
string a = "this is made by AI";
cout << a;
```
**Output**
```
this is made by AI
```
### I.4-e: string_view
Là 1 cách để đọc chuỗi không cần cấp phát bộ nhớ, không lưu dữ liệu, chỉ đọc không thao tác được.
```cpp
string a = "hahehu";
string_view s = a.substr(2,3);//substr để trích chuỗi
cout << s;
```
**Output**
```
he
//chuỗi ban đầu là hahehu nhưng do sử dụng substr nên chỉ đọc he.
```
### I.4-f: fstream
### I.4-g: ifstream
### I.4-h: ofstream
### I.4-i: stringstream
### I.4-j: istringstream
### I.4-k: ostringstream
### I.4-l: char8_t (C++20)
### I.4-m: char16_t
### I.4-n: char32_t
### I.4-o: istream
Là 1 khái niệm chỉ đầu vào thường là trong thư viện iostream hoặc fstream tên đầy đủ là inputstream.
### I.4-p: ostream
Giống cái trên nhưng chỉ đầu ra.
### I.4-q: cin
Nhập từ bàn phím để có dữ liệu đầu vào
```cpp=
int a;
cin >>a;
cout << a;
```
### I.4-r: cout
Xuất ra dữ liệu/yêu cầu bài toán.
```cpp=
int a;
cin >> a;
cout << a;
```
### I.4-s: cerr
Xuất ra lỗi và debug cũng trong thư viện iostream.
```cpp=
int a;
cin >> a;
if(a == 0)
{
cerr << "Sai";
}
```
### I.4-t: clog
Giống cerr nhưng có thể giữ lại trước khi xuất.
```cpp=
int a;
cin >> a;
clog << a+1;
```
### I.4-u: Escape Character ('\n', '\\', '\'', '\"', ...)
Những code trên là kiểu dữ liệu char dùng để biểu thị 1 dấu hay 1 cái gì đó đặc biệt không thể nhấn bình thường.
```cpp=
cout << "a\n"; // xuất ra chữ a xong xuống dòng.
cout << "\ta\n"; //Tab vô 1 lần xuất ra chữ a rồi xuống dòng.
cout << "\' \\ \""; //code "\\" để ghi ra dấu '\',\" để ghi ra dấu '"', code \' để ghi ra dấu '''
```
**Output**
```cpp=
a
a
' \ "
```
### I.4-v: Escape Sequence ('\nnn', '\o{nnn}', '\xnnn', '\x{nnn}', ...)
Là code để biến 1 số thành 1 kí tự nhưng nâng cao hơn giống như biến từ số thành bit. Có khá ít thông tin và không rõ lắm về nó nên em chưa tìm được ví dụ cụ thể.
### I.4-w: wchar_t
Là kiểu dữ liệu rộng hơn char về mặt dung lượng và có thể chứa kiểu dữ liệu unicode như các dấu trong tiếng việt, tiếng trung, emoji,...
```
wchar_t a='ê';
```
### I.4-x: wcin
Nhập kiểu dữ liệu trên.
```cpp=
wchar_t a;
wcin >> a;
```
### I.4-y: wcout
Xuất kiểu dữ liệu 4w.
```cpp=
wchar_t a;
wcin >> a;
cout << a;
```
**Input**
```
ơ
```
**Output**
```
ơ
```
:::
## I.5 - Bool & Bit
### I.5-a: bool
Là một kiểu dữ liệu lưu giá trị ĐÚNG(1) / SAI(0) hay còn được gọi là boolean
### I.5-b: byte (C++17)
### I.5-c: `vector<bool>`
### I.5-d: `bitset<SIZE>`