Prefix và Suffix
String Prefixes (Tiền tố chuỗi)
Các tiền tố (prefix) dùng trước ký tự và chuỗi trong C++
Tiền tố | Ý nghĩa | Kiểu dữ liệu | Kích thước phần tử | Mã hóa | Ví dụ |
---|---|---|---|---|---|
(trống) | Chuỗi/ký tự mặc định | char (ký tự), char[] (chuỗi) | 1 byte | ASCII hoặc mã hóa hệ thống | 'a' , "hello" |
L | Chuỗi/ký tự rộng | wchar_t | 2 hoặc 4 bytes (phụ thuộc nền tảng) | UTF-16 (Windows) hoặc UTF-32 (Linux) | L'a' , L"hello" |
u | Chuỗi/ký tự Unicode 16-bit | char16_t | 2 bytes | UTF-16 | u'a' , u"hello" |
U | Chuỗi/ký tự Unicode 32-bit | char32_t | 4 bytes | UTF-32 | U'a' , U"hello" |
u8 | Chuỗi UTF-8 | char (C++20: char8_t ) | 1 byte | UTF-8 | u8"a" , u8"hello" |
R | Chuỗi thô | const char* | N/A | ASCII hoặc mã hóa hệ thống | R"C:\user\Admin" |
Giải thích chi tiết
- Không tiền tố (trống):
- Dùng cho ký tự (
char
) hoặc chuỗi (char[]
) thông thường. - Mã hóa phụ thuộc hệ thống (thường là ASCII hoặc mã hóa mặc định).
- Phù hợp với văn bản tiếng Anh cơ bản hoặc khi không cần hỗ trợ Unicode.
- Lưu ý: Không đảm bảo hỗ trợ ký tự tiếng Việt nếu mã hóa hệ thống không phải UTF-8.
- Dùng cho ký tự (
L
(Wide character/string):- Dùng cho ký tự (
wchar_t
) hoặc chuỗi rộng (wchar_t[]
). - Kích thước phụ thuộc nền tảng: Windows (2 bytes, UTF-16), Linux (4 bytes, UTF-32).
- Thích hợp cho ứng dụng đa ngôn ngữ trên Windows (API Win32).
- Lưu ý: Kích thước không đồng nhất, cần cẩn thận khi chuyển đổi.
- Dùng cho ký tự (
u
(UTF-16):- Dùng cho ký tự (
char16_t
) hoặc chuỗi Unicode 16-bit. - Đảm bảo mã hóa UTF-16, phù hợp với văn bản Unicode cố định.
- Lưu ý: Ít dùng trực tiếp, thường dùng trong thư viện hoặc xử lý văn bản.
- Dùng cho ký tự (
U
(UTF-32):- Dùng cho ký tự (
char32_t
) hoặc chuỗi Unicode 32-bit. - Mã hóa UTF-32, đảm bảo kích thước cố định (4 bytes).
- Phù hợp khi cần xử lý toàn bộ điểm mã Unicode (code points).
- Lưu ý: Tốn bộ nhớ hơn
u8
.
- Dùng cho ký tự (
u8
(UTF-8):- Dùng cho chuỗi UTF-8 (
char
hoặcchar8_t
từ C++20). - Tiết kiệm bộ nhớ, tương thích tốt với hệ thống hiện đại.
- Lý tưởng cho ứng dụng web, tệp văn bản, hoặc hỗ trợ tiếng Việt.
- Lưu ý: C++20 giới thiệu
char8_t
để phân biệt rõ ràng chuỗi UTF-8.
- Dùng cho chuỗi UTF-8 (
R
(Raw String Literal):- Chỉ định một chuỗi ký tự thô, cho phép viết chuỗi mà không cần escape các ký tự đặc biệt (như
\n
,\t
,\"
). Chuỗi được giữ nguyên như cú pháp trong mã. - Dùng cho đường dẫn file Windows, regex, JSON, hoặc chuỗi chứa nhiều ký tự đặc biệt.
- Kết hợp R với các tiền tố khác:
u8R
(Raw UTF-8 String Literal):- Ý nghĩa: Chuỗi UTF-8 thô, không cần escape.
- Kiểu dữ liệu:
const char*
(C++11-17) hoặcconst char8_t*
(C++20). - Ứng dụng: Chuỗi UTF-8 chứa ký tự đặc biệt, như JSON hoặc regex tiếng Việt.
uR
(Raw UTF-16 String Literal):- Ý nghĩa: Chuỗi UTF-16 thô, không cần escape.
- Kiểu dữ liệu:
const char16_t*
. - Ứng dụng: Hiếm dùng trên Windows, nhưng hữu ích trong ứng dụng cross-platform.
UR
(Raw UTF-32 String Literal):- Ý nghĩa: Chuỗi UTF-32 thô, không cần escape.
- Kiểu dữ liệu:
const char32_t*
. - Ứng dụng: Xử lý Unicode đầy đủ với chuỗi chứa ký tự đặc biệt.
LR
(Raw Wide String Literal):- Ý nghĩa: Chuỗi rộng (UTF-16 trên Windows) thô, không cần escape.
- Kiểu dữ liệu:
const wchar_t*
. - Ứng dụng: Dùng với Windows API (Win32, COM) khi cần chuỗi Unicode chứa ký tự đặc biệt.
- Chỉ định một chuỗi ký tự thô, cho phép viết chuỗi mà không cần escape các ký tự đặc biệt (như
Ví dụ
#include <iostream>
#include <string>
int main() {
// Không tiền tố: Chuỗi ASCII
const char* str1 = "Xin chào";
std::cout << str1 << std::endl;
// L: Chuỗi rộng
const wchar_t* str2 = L"Xin chào";
std::wcout << str2 << std::endl;
// u: Chuỗi UTF-16
const char16_t* str3 = u"Xin chào";
std::cout << "UTF-16 string length: " << std::u16string(str3).length() << std::endl;
// U: Chuỗi UTF-32
const char32_t* str4 = U"Xin chào";
std::cout << "UTF-32 string length: " << std::u32string(str4).length() << std::endl;
// u8: Chuỗi UTF-8
const char8_t* str5 = u8"Xin chào";
// Chuyển đổi sang std::string để in
std::string str5_converted(reinterpret_cast<const char*>(str5));
std::cout << str5_converted << std::endl;
const char* rawStr = R"(C:\Program Files\nNoEscape)";
std::cout << rawStr << std::endl; // In: C:\Program Files\nNoEscape
const char8_t* rawUtf8 = u8R"(Xin chào\nViệt Nam!)";
// Chuyển đổi sang std::string để in
std::string str(reinterpret_cast<const char*>(rawUtf8));
std::cout << str << std::endl; // In: Xin chào\nViệt Nam!
return 0;
}
Number suffixes (Hậu tố số)
Các hậu tố (suffix) dùng sau số nguyên và số thực trong C++
Hậu tố | Ý nghĩa | Kiểu dữ liệu | Ví dụ |
---|---|---|---|
(trống) | Số nguyên hoặc số thực mặc định | int hoặc double | 42 , 3.14 |
u hoặc U | Số nguyên không dấu | unsigned int | 42u , 42U |
l hoặc L | Số nguyên dài | long | 42l , 42L |
ul hoặc UL | Số nguyên dài không dấu | unsigned long | 42ul , 42UL |
ll hoặc LL | Số nguyên rất dài | long long | 42ll , 42LL |
ull hoặc ULL | Số nguyên rất dài không dấu | unsigned long long | 42ull , 42ULL |
f hoặc F | Số thực độ chính xác đơn | float | 3.14f , 3.14F |
l hoặc L | Số thực độ chính xác cao | long double | 3.14l , 3.14L |
Giải thích ghi chú
- Mặc định (không hậu tố):
- Số nguyên:
int
(thường 4 bytes, phụ thuộc nền tảng). - Số thực:
double
(thường 8 bytes, độ chính xác cao hơnfloat
). - Ví dụ:
42
làint
,3.14
làdouble
.
- Số nguyên:
- Phân biệt hoa/thường:
- Không có khác biệt giữa
u
vàU
,l
vàL
,ll
vàLL
,f
vàF
. - Khuyến nghị: Dùng chữ hoa (
U
,L
,ULL
,F
) để dễ đọc và thống nhất.
- Không có khác biệt giữa
- Kết hợp hậu tố:
- Chỉ áp dụng cho số nguyên:
ul
(unsigned long),ull
(unsigned long long). - Không có kết hợp cho số thực (ví dụ: không có
fl
).
- Chỉ áp dụng cho số nguyên:
- Lưu ý quan trọng:
- Số nguyên quá lớn mà không có hậu tố
ll
/ull
có thể gây lỗi biên dịch (overflow). - Số thực không có hậu tố là
double
, cầnf
để ép kiểu thànhfloat
. - Kiểm tra kích thước kiểu dữ liệu bằng
sizeof
khi làm việc trên nhiều nền tảng.
- Số nguyên quá lớn mà không có hậu tố
Ví dụ
#include <iostream>
int main() {
// Số nguyên mặc định
int x = 42; // int
std::cout << "int: " << x << ", size: " << sizeof(x) << " bytes\n";
// Số nguyên không dấu
unsigned int y = 42U; // unsigned int
std::cout << "unsigned int: " << y << ", size: " << sizeof(y) << " bytes\n";
// Số nguyên dài
long z = 42L; // long
std::cout << "long: " << z << ", size: " << sizeof(z) << " bytes\n";
// Số nguyên rất dài không dấu
unsigned long long w = 42ULL; // unsigned long long
std::cout << "unsigned long long: " << w << ", size: " << sizeof(w) << " bytes\n";
// Số thực độ chính xác đơn
float f = 3.14f; // float
std::cout << "float: " << f << ", size: " << sizeof(f) << " bytes\n";
// Số thực độ chính xác cao
long double ld = 3.14L; // long double
std::cout << "long double: " << ld << ", size: " << sizeof(ld) << " bytes\n";
return 0;
}
Hậu tố z
/Z
(C++23, Signed Size Type)
- Ý nghĩa: Chỉ định số nguyên có kích thước phù hợp với kiểu
std::size_t
(hoặc kiểu signed tương ứng, nhưstd::ssize_t
). - Kiểu dữ liệu: Kiểu
signed
tương ứng vớistd::size_t
(thường làlong
hoặclong long
, tùy nền tảng). - Ứng dụng: Dùng khi cần số nguyên có kích thước phù hợp với kích thước bộ nhớ (như chỉ số mảng, kích thước container).
- Ví dụ:
#include <iostream>
int main() {
auto x = 42z; // Kiểu signed tương ứng với size_t
std::cout << "Value: " << x << ", Size: " << sizeof(x) << " bytes\n";
return 0;
}
Hậu tố uz
/UZ
(C++23, Unsigned Size Type)
- Ý nghĩa: Chỉ định số nguyên không dấu có kích thước phù hợp với
std::size_t
. - Kiểu dữ liệu:
std::size_t
(thường làunsigned long
hoặcunsigned long long
). - Ứng dụng: Dùng cho các giá trị không âm, như kích thước mảng hoặc chỉ số.
- Ví dụ:
#include <iostream>
int main() {
auto x = 42uz; // std::size_t
std::cout << "Value: " << x << ", Size: " << sizeof(x) << " bytes\n";
return 0;
}
Hậu tố cho số bát phân và nhị phân
- Số bát phân: Bắt đầu bằng
0
(không phải hậu tố, mà là tiền tố cơ số).- Ví dụ:
042
là 34 (cơ số 10), kiểuint
.
- Ví dụ:
- Số nhị phân: Bắt đầu bằng
0b
hoặc0B
(C++14 trở lên).- Ví dụ:
0b1010
là 10 (cơ số 10), kiểuint
.
- Ví dụ: