Trong lập trình C, kiểu dữ liệu (data type) quyết định loại giá trị mà một biến có thể lưu trữ. Việc hiểu và sử dụng đúng kiểu dữ liệu là bước đầu tiên để viết chương trình chính xác, tiết kiệm bộ nhớ và tránh lỗi.

🧩 1. Kiểu Dữ Liệu Và Đặc Tả (Data Type & Format Specifier)

Mỗi kiểu dữ liệu trong C được xác định bởi:

  • Tên kiểu (Data Type Name): như int, float, char

  • Kích thước bộ nhớ (Memory Size): tính bằng byte.

  • Phạm vi lưu trữ (Value Range): giá trị thấp nhất – cao nhất.

  • Đặc tả định dạng (Format Specifier): dùng trong hàm printf() hoặc scanf() để in/nhập dữ liệu tương ứng.

Bảng tổng hợp các kiểu dữ liệu phổ biến:

Kiểu dữ liệu Kích thước (byte) Phạm vi giá trị Đặc tả (printf)
short 2 -32,768 đến 32,767 %hi
unsigned short 2 0 đến 65,535 %hu
int 4 -2,147,483,648 đến 2,147,483,647 %d
unsigned int 4 0 đến 4,294,967,295 %u
long long 8 -9,223,372,036,854,775,808 đến 9,223,372,036,854,775,807 %lld
unsigned long long 8 0 đến 18,446,744,073,709,551,615 %llu
char 1 -128 đến 127 (signed) / 0 đến 255 (unsigned) %c
float 4 ~ ±3.4 × 10^±38 (6-7 chữ số thập phân) %f
double 8 ~ ±1.7 × 10^±308 (15-16 chữ số thập phân) %lf

🔢 2. Kiểu Dữ Liệu Số Nguyên (Integer Types)

Khái niệm:

Các kiểu số nguyên dùng để lưu các số không có phần thập phân (ví dụ: 1, -7, 2025…).

Các loại chính:

  • int: Loại phổ biến nhất.

  • long long: Dùng khi cần lưu số rất lớn (ví dụ: dữ liệu thống kê, tính toán tài chính).

  • unsigned: Dùng khi chắc chắn rằng số không bao giờ âm (ví dụ: tuổi, số lượng, chỉ số…).

Lưu ý quan trọng:

  • Số nguyên không thể chứa dấu chấm động, vì vậy int x = 3.14; sẽ gây lỗi hoặc mất dữ liệu.

  • Các kiểu signed cho phép lưu số âm và dương.

  • Các kiểu unsigned chỉ lưu được số dương nhưng dải giá trị lớn gấp đôi phần dương của signed.

  • Nếu gán giá trị vượt giới hạn → xảy ra tràn số (overflow) và kết quả sẽ sai.

Công thức tính phạm vi:

Giả sử một kiểu dùng n bit:

  • Có dấu (signed): -2^(n-1)2^(n-1) - 1

  • Không dấu (unsigned): 02^n - 1

Ví dụ:

  • int dùng 4 byte = 32 bit → -2^312^31 - 1 ≈ -2.1 tỷ đến +2.1 tỷ

  • unsigned int → 0 → 2^32 - 1 ≈ 4.2 tỷ

3. Kiểu Dữ Liệu Số Thực (Floating Point Types)

 Khái niệm:

Dùng để lưu các số có phần thập phân (ví dụ: 3.1415, -0.005, 100.0…).

Các loại chính:

Kiểu Độ chính xác Số chữ số phần thập phân Dải giá trị xấp xỉ
float Đơn (single) ~6-7 chữ số 10^-38 → 10^+38
double Kép (double) ~15-16 chữ số 10^-308 → 10^+308

Lưu ý:

  • Trong hầu hết các chương trình thực tế, bạn nên ưu tiên dùng double để tránh sai số tích lũy khi tính toán phức tạp.

  • Không nên dùng kiểu số thực để lưu các giá trị cần chính xác tuyệt đối (ví dụ: số tiền, đếm số lượng).

🔡 4. Kiểu Ký Tự (Character Type)

 Khái niệm:

  • Dùng để lưu một ký tự duy nhất.

  • Dữ liệu được lưu ở dạng mã hóa ASCII hoặc UTF-8 (nếu môi trường hỗ trợ).

  • Một ký tự như 'A', 'b', '5', '@' sẽ được lưu dưới dạng số nguyên tương ứng.

 Chi tiết:

  • char là kiểu dữ liệu kích thước nhỏ nhất: 1 byte = 8 bit

  • Có thể lưu: chữ cái, số, ký tự đặc biệt.

  • Ví dụ: 'A' tương ứng với mã ASCII là 65.

Lưu ý:

  • char chỉ lưu được 1 ký tự duy nhất, không phải chuỗi (string).

  • Để lưu nhiều ký tự, bạn cần sử dụng mảng ký tự hoặc con trỏ (char arr[], char *str).

 5. Làm Thế Nào Chọn Kiểu Dữ Liệu Phù Hợp?

Tình huống Kiểu nên dùng
Số nguyên nhỏ (tuổi, điểm, đếm số) int
Số nguyên lớn (dân số, thống kê số liệu lớn) long long
Giá trị không bao giờ âm (chỉ số, tuổi) unsigned int
Số thực chính xác thấp (kết quả trung gian) float
Số thực cần tính toán nhiều, yêu cầu độ chính xác double
Lưu một ký tự (A-Z, ký tự đặc biệt) char