Chuyển tới nội dung chính

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.

1. Các kiểu dữ liệu cơ bản (Fundamental Types)

Các kiểu dữ liệu cơ bản là nền tảng của C++, được trình biên dịch hỗ trợ trực tiếp. Bao gồm số nguyên, số thực, ký tự, và logic.

Kiểu số nguyên có dấu (Signed Integral Types)

KiểuKích thước 32-bit/64-bitPhạm vi
char1 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)
short2 byte / 2 byte-32,768 đến 32,767
int4 byte / 4 byte-2,147,483,648 đến 2,147,483,647
long4 byte / 4 byte (Windows), 8 byte (Linux)-2,147,483,648 đến 2,147,483,647 (Windows)
long long8 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 Integral Types)

KiểuKích thướcPhạm vi
unsigned char1 byte0 đến 255
unsigned short2 byte0 đến 65,535
unsigned int4 byte0 đến 4,294,967,295
unsigned long4 byte (Win), 8 byte (Linux)0 đến 4,294,967,295 (Windows)
unsigned long long8 byte0 đến 18,446,744,073,709,551,615

Kiểu cố định kích thước (Fixed-Width Types, từ <cstdint>)

KiểuKích thướcPhạm vi
int8_t1 byte-128 đến 127
uint8_t1 byte0 đến 255
int32_t4 byte-2,147,483,648 đến 2,147,483,647
uint32_t4 byte0 đến 4,294,967,295
int64_t8 byte-9,223,372,036,854,775,808 đến 9,223,372,036,854,775,807
uint64_t8 byte0 đến 18,446,744,073,709,551,615

Kiểu số thực (Floating-Point Types)

KiểuKích thướcPhạm vi gần đúng
float4 byte~ ±1.2×10⁻³⁸ đến ±3.4×10³⁸
double8 byte~ ±2.3×10⁻³⁰⁸ đến ±1.7×10³⁰⁸
long double8 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ự (Boolean and Character Types)

KiểuKích thướcGhi chú
bool1 byteChỉ nhận true hoặc false
char1 byteMã ASCII ký tự (signed trên MSVC, unsigned trên một số trình biên dịch)
wchar_t2 byte (Windows), 4 byte (Linux)Dùng cho ký tự Unicode rộng
char16_t2 byteUTF-16
char32_t4 byteUTF-32

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";
}

2. Các kiểu tổng hợp (Compound Types)

Các kiểu tổng hợp được xây dựng từ kiểu cơ bản, bao gồm mảng, con trỏ, tham chiếu, và hàm.

Mảng (Array)

Tập hợp các phần tử cùng kiểu, kích thước cố định hoặc động (C++11 trở lên với std::vector).

int arr[5] = {1, 2, 3, 4, 5}; // Mảng tĩnh
std::vector<int> vec = {1, 2, 3}; // Mảng động

Con trỏ (Pointer)

  • Định nghĩa: Biến lưu địa chỉ bộ nhớ.
  • Kích thước: 4 byte (32-bit), 8 byte (64-bit).
int x = 10;
int* ptr = &x; // Con trỏ đến int

Tham chiếu (Reference)

Bí danh (alias) của một biến hiện có, không chiếm bộ nhớ riêng.

int x = 10;
int& ref = x; // Tham chiếu đến x
ref = 20; // Thay đổi x

Hàm (Function Types)

Kiểu biểu diễn chữ ký hàm (tham số và kiểu trả về).

using FuncPtr = int(*)(int, int); // Con trỏ hàm
int add(int a, int b) { return a + b; }
FuncPtr ptr = add;

3. Các kiểu do người dùng định nghĩa (User-Defined Types)

Các kiểu do người dùng định nghĩa để tổ chức dữ liệu và hành vi.

Class và Struct

  • Định nghĩa: Tổ chức dữ liệu và hàm thành viên, hỗ trợ OOP.
  • Khác biệt: struct mặc định public, class mặc định private.
struct Point {
int x, y;
int distance() const { return x * x + y * y; }
};

Union

Lưu trữ nhiều kiểu dữ liệu trong cùng một vùng bộ nhớ, chỉ một thành viên có giá trị tại một thời điểm.

union Variant {
int i;
float f;
};

Enum

Tập hợp các hằng số nguyên có tên.

enum class Color { Red, Green, Blue }; // C++11, scoped enum
Color c = Color::Red;

Closure Type

Kiểu ẩn danh biểu diễn lambda expression (C++11), là một lớp với operator().

auto lambda = [](int x) { return x * x; };
std::cout << lambda(5) << '\n'; // 25

4. Các kiểu đặc biệt khác (Other Special Types)

void

  • Định nghĩa: Biểu thị không có giá trị hoặc kiểu trả về.
  • Sử dụng: Hàm không trả về, con trỏ void (void*).
void* ptr = nullptr; // Con trỏ chung

auto

Tự động suy ra kiểu từ giá trị khởi tạo (C++11).

auto x = 42; // int
auto y = std::vector<int>{1, 2, 3}; // std::vector<int>

decltype

Suy ra kiểu của biểu thức tại thời điểm biên dịch.

int x = 10;
decltype(x) y = 20; // y là int

Kiểu size và con trỏ

KiểuKích thước 32-bit/64-bitGhi chú
size_t4 byte / 8 byteKiểu unsigned dùng cho kích thước mảng
ptrdiff_t4 byte / 8 byteKiểu signed, dùng cho hiệu 2 con trỏ
void*4 byte / 8 byteKích thước con trỏ

Kiểu dữ liệu Windows API (thường gặp trong Windows SDK)

Các kiểu Windows API được định nghĩa trong <Windows.h>, dùng trong lập trình hệ thống Windows.

Nhóm kiểu số nguyên cơ bản (Windows-style)

Kiểu WindowsTương đương C++Kích thước (bytes)Ghi chú
BYTEunsigned char18-bit không dấu
CHARchar18-bit có dấu
SHORTshort216-bit có dấu
USHORTunsigned short216-bit không dấu
WORDunsigned short2thường dùng trong struct
INTint432-bit có dấu
UINTunsigned int432-bit không dấu
LONGlong4luôn 32-bit (dù 64-bit OS)
ULONGunsigned long4
DWORDunsigned long4"Double Word" (2×16-bit)
BOOLint4Giá 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 WindowsKiểu tương đươngKích thước (bytes) (x86/x64)Mục đích
INT_PTRintptr_t4 / 8Số nguyên đủ lớn để chứa con trỏ
UINT_PTRuintptr_t4 / 8unsigned version
LONG_PTRlong/long long4 / 8Như INT_PTR, dùng cho LONG-style
ULONG_PTRunsigned long/ULL4 / 8unsigned version của LONG_PTR
SIZE_Tsize_t4 / 8Kích thước bộ nhớ
SSIZE_Tptrdiff_t4 / 8signed version của SIZE_T
HANDLEvoid*4 / 8Con trỏ trừu tượng (file, mutex,...)
LPVOIDvoid*4 / 8Con trỏ void
LPCVOIDconst void*4 / 8Con 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 WindowsTương đương C++Kích thước (bytes) (x86/x64)Mục đích
LPSTRchar*4 / 8Con trỏ đến chuỗi ANSI
LPCSTRconst char*4 / 8Con trỏ hằng đến chuỗi ANSI
LPWSTRwchar_t*4 / 8Con trỏ đến chuỗi Unicode rộng
LPCWSTRconst wchar_t*4 / 8Con 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ơn LPSTR (ANSI) trong các ứng dụng hiện đại.
  • Best practice:
    • Sử dụng uint32_t thay DWORDconst void* thay LPCVOID 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ặc LPWSTR không null trước khi sử dụng.
    • Dùng static_cast khi ép kiểu từ LPCVOID hoặc LPCWSTR để đảm bảo an toàn kiểu.