Kiểu dữ liệu trong C++
Dưới đây là bảng liệt kê các kiểu dữ liệu thường dùng trong C++ cùng kích thước và phạm vi của chúng trong môi trường 32-bit và 64-bit (tuân theo chuẩn phổ biến hiện nay: LP32 và LLP64), bao gồm các kiểu dữ liệu định nghĩa bởi Windows API. Lưu ý rằng kích thước và phạm vi có thể phụ thuộc vào trình biên dịch và hệ điều hành, nhưng các giá trị dưới đây là phổ biến cho các hệ thống Windows.
Kiểu số nguyên có dấu (signed)
Kiểu | Kích thước 32-bit/64-bit | Phạm vi |
---|---|---|
char | 1 byte / 1 byte | -128 đến 127 (mặc định signed trên MSVC, unsigned trên một số trình biên dịch khác) |
short | 2 byte / 2 byte | -32,768 đến 32,767 |
int | 4 byte / 4 byte | -2,147,483,648 đến 2,147,483,647 |
long | 4 byte / 4 byte (Windows), 8 byte (Linux) | -2,147,483,648 đến 2,147,483,647 (Windows) |
long long | 8 byte / 8 byte | -9,223,372,036,854,775,808 đến +9,223,372,036,854,775,807 |
Kiểu số nguyên không dấu (unsigned)
Kiểu | Kích thước | Phạm vi |
---|---|---|
unsigned char | 1 byte | 0 đến 255 |
unsigned short | 2 byte | 0 đến 65,535 |
unsigned int | 4 byte | 0 đến 4,294,967,295 |
unsigned long | 4 byte (Win), 8 byte (Linux) | 0 đến 4,294,967,295 (Windows) |
unsigned long long | 8 byte | 0 đến 18,446,744,073,709,551,615 |
Kiểu cố định kích thước (từ <cstdint>
)
Kiểu | Kích thước | Phạm vi |
---|---|---|
int8_t | 1 byte | -128 đến 127 |
uint8_t | 1 byte | 0 đến 255 |
int32_t | 4 byte | -2,147,483,648 đến 2,147,483,647 |
uint32_t | 4 byte | 0 đến 4,294,967,295 |
int64_t | 8 byte | -9,223,372,036,854,775,808 đến 9,223,372,036,854,775,807 |
uint64_t | 8 byte | 0 đến 18,446,744,073,709,551,615 |
Kiểu thực (float, double)
Kiểu | Kích thước | Phạm vi gần đúng |
---|---|---|
float | 4 byte | ~ ±1.2×10⁻³⁸ đến ±3.4×10³⁸ |
double | 8 byte | ~ ±2.3×10⁻³⁰⁸ đến ±1.7×10³⁰⁸ |
long double | 8 byte (MSVC), 10/16 byte (GCC) | phạm vi lớn hơn double (phụ thuộc trình biên dịch) |
Kiểu logic & ký tự
Kiểu | Kích thước | Ghi chú |
---|---|---|
bool | 1 byte | Chỉ nhận true hoặc false |
char | 1 byte | Mã ASCII ký tự (signed trên MSVC, unsigned trên một số trình biên dịch) |
wchar_t | 2 byte (Windows), 4 byte (Linux) | Dùng cho ký tự Unicode rộng |
char16_t | 2 byte | UTF-16 |
char32_t | 4 byte | UTF-32 |
Kiểu size và con trỏ
Kiểu | Kích thước 32-bit/64-bit | Ghi chú |
---|---|---|
size_t | 4 byte / 8 byte | Kiểu unsigned dùng cho kích thước mảng |
ptrdiff_t | 4 byte / 8 byte | Kiểu signed, dùng cho hiệu 2 con trỏ |
void* | 4 byte / 8 byte | Kích thước con trỏ |
Kiểm tra thực tế:
#include <iostream>
#include <typeinfo>
#include <cstddef>
int main() {
std::cout << "int: " << sizeof(int) << " bytes\n";
std::cout << "long: " << sizeof(long) << " bytes\n";
std::cout << "long long: " << sizeof(long long) << " bytes\n";
std::cout << "size_t: " << sizeof(size_t) << " bytes\n";
std::cout << "void*: " << sizeof(void*) << " bytes\n";
std::cout << "int32_t: " << sizeof(int32_t) << " bytes\n";
std::cout << "uint64_t: " << sizeof(uint64_t) << " bytes\n";
}
Kiểu dữ liệu Windows API (thường gặp trong Windows SDK)
Nhóm kiểu số nguyên cơ bản (Windows-style)
Kiểu Windows | Tương đương C++ | Kích thước (bytes) | Ghi chú |
---|---|---|---|
BYTE | unsigned char | 1 | 8-bit không dấu |
CHAR | char | 1 | 8-bit có dấu |
SHORT | short | 2 | 16-bit có dấu |
USHORT | unsigned short | 2 | 16-bit không dấu |
WORD | unsigned short | 2 | thường dùng trong struct |
INT | int | 4 | 32-bit có dấu |
UINT | unsigned int | 4 | 32-bit không dấu |
LONG | long | 4 | luôn 32-bit (dù 64-bit OS) |
ULONG | unsigned long | 4 | |
DWORD | unsigned long | 4 | "Double Word" (2×16-bit) |
BOOL | int | 4 | Giá trị logic (0 = false, khác 0 = true) |
- Trên Windows 64-bit,
LONG
vẫn là 4 byte (vì LLP64 model).
Nhóm kiểu địa chỉ/phụ thuộc kiến trúc (Pointer-sized)
Kiểu Windows | Kiểu tương đương | Kích thước (bytes) (x86/x64) | Mục đích |
---|---|---|---|
INT_PTR | intptr_t | 4 / 8 | Số nguyên đủ lớn để chứa con trỏ |
UINT_PTR | uintptr_t | 4 / 8 | unsigned version |
LONG_PTR | long /long long | 4 / 8 | Như INT_PTR , dùng cho LONG -style |
ULONG_PTR | unsigned long /ULL | 4 / 8 | unsigned version của LONG_PTR |
SIZE_T | size_t | 4 / 8 | Kích thước bộ nhớ |
SSIZE_T | ptrdiff_t | 4 / 8 | signed version của SIZE_T |
HANDLE | void* | 4 / 8 | Con trỏ trừu tượng (file, mutex,...) |
LPVOID | void* | 4 / 8 | Con trỏ void |
LPCVOID | const void* | 4 / 8 | Con trỏ hằng đến dữ liệu bất kỳ |
- Những kiểu này thường dùng trong các hàm WinAPI để hỗ trợ xử lý địa chỉ, pointer, kích thước bộ nhớ trên cả 32-bit và 64-bit.
Nhóm kiểu chuỗi (Windows-style)
Kiểu Windows | Tương đương C++ | Kích thước (bytes) (x86/x64) | Mục đích |
---|---|---|---|
LPSTR | char* | 4 / 8 | Con trỏ đến chuỗi ANSI |
LPCSTR | const char* | 4 / 8 | Con trỏ hằng đến chuỗi ANSI |
LPWSTR | wchar_t* | 4 / 8 | Con trỏ đến chuỗi Unicode rộng |
LPCWSTR | const wchar_t* | 4 / 8 | Con trỏ hằng đến chuỗi Unicode rộng |
Kiểm tra thực tế:
#include <iostream>
#include <Windows.h>
int main() {
std::cout << "DWORD: " << sizeof(DWORD) << '\n';
std::cout << "LONG_PTR: " << sizeof(LONG_PTR) << '\n';
std::cout << "UINT_PTR: " << sizeof(UINT_PTR) << '\n';
std::cout << "HANDLE: " << sizeof(HANDLE) << '\n';
std::cout << "LPCVOID: " << sizeof(LPCVOID) << " bytes\n";
std::cout << "LPCWSTR: " << sizeof(LPCWSTR) << " bytes\n";
// Ví dụ sử dụng LPCVOID
const char* text = "Test";
LPCVOID buffer = static_cast<LPCVOID>(text);
std::cout << "Buffer data: " << static_cast<const char*>(buffer) << "\n";
}
Ghi chú:
- Môi trường 32-bit và 64-bit: Sự khác biệt chủ yếu nằm ở kích thước con trỏ và các kiểu liên quan (
LPSTR
,HANDLE
,...). Các kiểu số nguyên (int
,long
,...) thường giữ nguyên kích thước giữa hai môi trường trên Windows. - Windows API: Các kiểu như
DWORD
,LONG
,... được định nghĩa trong<Windows.h>
để đảm bảo tính tương thích. Chúng thường ánh xạ đến các kiểu C++ cơ bản. - Phụ thuộc trình biên dịch: Một số kiểu như
long double
có thể khác nhau (ví dụ, trên GCC,long double
có thể là 10 hoặc 16 bytes). - Unicode vs ANSI: Windows API sử dụng
LPWSTR
(Unicode) phổ biến hơnLPSTR
(ANSI) trong các ứng dụng hiện đại. - Best practice:
- Sử dụng
uint32_t
thayDWORD
vàconst void*
thayLPCVOID
trong mã di động để đảm bảo tính tương thích trên nhiều nền tảng. - Luôn kiểm tra con trỏ như
LPCVOID
,HANDLE
, hoặcLPWSTR
không null trước khi sử dụng. - Dùng
static_cast
khi ép kiểu từLPCVOID
hoặcLPCWSTR
để đảm bảo an toàn kiểu.
- Sử dụng