Các kiểu dữ liệu trong C (Data type) người dùng cần biết

C là một ngôn ngữ lập trình mạnh mẽ và phổ biến để phát triển hệ điều hành, cơ sở dữ liệu... Đây cũng là một ngôn ngữ tuyệt vời để một người mới bắt đầu học tập. Trong vô vàn kiến thức, bạn sẽ cần phải hiểu rõ về các kiểu dữ liệu của C để có thể làm việc với ngôn ngữ lập trình này. Vì vậy, những kiến thức về sau có thể giúp bạn biết kiểu dữ liệu nào cần cũng như những thao tác nào có thể được thực hiện.

Mục lục

Trong blog này, hãy cùng TechWorks tìm hiểu các kiểu dữ liệu trong C và xem xét các kiểu dữ liệu khác nhau như thế nào.

Kiểu dữ liệu trong C là gì?

Kiểu dữ liệu trong C là gì?

Kiểu dữ liệu (data type) là một khái niệm trong lập trình, dùng để xác định loại dữ liệu mà một biến có thể lưu trữ và cách dữ liệu đó được xử lý trong chương trình. Nói cách khác, kiểu dữ liệu quyết định kích thước bộ nhớ cần thiết, cách dữ liệu được lưu trữ trong bộ nhớ, và các thao tác có thể thực hiện trên dữ liệu đó.

Ví dụ:

  • Số nguyên: Lưu trữ các số nguyên (như -10, 0, 100).
  • Số thực: Lưu trữ các số có phần thập phân (như 3.14, -0.5).
  • Ký tự: Lưu trữ một ký tự duy nhất (như 'A', 'b', '@').
  • Chuỗi: Lưu trữ một dãy ký tự (như "Hello", "123").
  • Con trỏ: Lưu trữ địa chỉ của một vùng nhớ.

Ví dụ về các kiểu dữ liệu trong C

Một công ty lưu trữ nhiều dữ liệu khác nhau của nhân viên như Tên, Mã số nhân viên, Tuổi, Lương, Địa chỉ, Số điện thoại...

Hiện tại, những dữ liệu này là các giá trị đa dạng như chữ cái, số.., do đó để xử lý lượng dữ liệu khổng lồ này cho các chương trình một cách dễ dàng, thông tin đã được phân loại thành các loại khác nhau:

  • Tên: Chuỗi
  • ID: Số nguyên
  • Lương: Float hoặc Double
  • Số điện thoại: Chuỗi

Bộ sửa đổi kiểu dữ liệu trong C 

Trong ngôn ngữ C, bộ sửa đổi kiểu dữ liệu (data type modifiers) là những từ khóa được sử dụng để thay đổi kích thước và phạm vi của các kiểu dữ liệu cơ bản như int, char, float, và double. Những bộ sửa đổi này giúp lập trình viên tối ưu hóa bộ nhớ và phù hợp với yêu cầu của chương trình. Các bộ sửa đổi trong C bao gồm:

  • signed: Cho phép lưu trữ cả số âm và dương (mặc định cho int và char).
  • unsigned: Chỉ lưu trữ số dương, phạm vi lớn hơn.
  • short: Giảm kích thước (thường với int).
  • long: Tăng kích thước để lưu trữ giá trị lớn hơn (với int và double).

Các trình sửa đổi này làm cho bộ nhớ cần thiết cho các kiểu dữ liệu chính trở nên chính xác hơn. 

Kích thước của các kiểu dữ liệu trong C

Kích thước của mỗi kiểu dữ liệu được đo bằng bit hoặc byte (8 bit). Mỗi kiểu dữ liệu trong C có một phạm vi giá trị cụ thể như sau: 

Kiểu dữ liệu Định dạng đặc tả ( Format Specifier) Vùng giá trị Kích thước theo bit
unsigned char %c 0 đến 255 8
char %c -127 đến 127 8
signed char %c -127 đến 127 8
int %d, %i -32.767 đến 32.767 16 hoặc 32
unsigned int %u 0 đến 65.535 16 hoặc 32
signed int %d, %i -32,767 đến 32,767 (giống như int) 16 hoặc 32
short int %hd -32.767 đến 32.767 16
unsigned short int %hu 0 đến 65.535 16
signed short int %hd Giống như short int 16
long int %ld, %li -2.147.483.647 đến 2.147.483.647 32
long long int %lld, %lli -(2^63) đến (2^63)-1 64
signed long int %ld, %li Giống như long int 32
unsigned long int %lu 0 đến 4.294.967.295 32
unsigned long long int %llu (2^63)-1 64
float %f 1E-37 to 1E+37 với độ chính xác là 6 vị trí thập phân 32
double %lf 1E-37 to 1E+37 với độ chính xác là 6 vị trí thập phân 64
long double %Lf 1E-37 to 1E+37 với độ chính xác là 6 vị trí thập phân 80

Có một sự thật thú vị mà TechWorks muốn chia sẻ đến bạn đó là double được gọi là double vì nó có thể chứa gấp đôi giá trị float.

Hiểu về Kiểu dữ liệu trong C theo Thuật ngữ Bộ nhớ

Kiểu dữ liệu dành một phần bộ nhớ để lưu trữ và biểu diễn một giá trị. Một byte đơn bao gồm 8 bit bộ nhớ. Hãy xem xét biểu diễn byte bên dưới, trong đó mỗi bit được biểu diễn bằng dấu gạch dưới (_):

byte: _ _ _ _ _ _ _ _ < – 8 bit

Vì chúng ta có 8 vị trí, chúng ta có thể nhập 0 hoặc 1. Vì vậy, chúng ta có thể có sự kết hợp của 2^8 hoặc 256 giá trị riêng biệt, có thể được biểu diễn từ 8 bit, là phạm vi tổng thể của một byte.

byte: 0 0 0 0 0 0 0 0 <- Biểu diễn “0”

byte: 0 0 0 0 0 0 0 0 1 <- Biểu diễn “1”

...............

byte: 1 1 1 1 1 1 1 1 0 <- Biểu diễn “254”

byte: 1 1 1 1 1 1 1 1 1 <- Biểu diễn “255”

Tương tự, chúng ta có,

int: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ < – 16 bit

long: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ < – 32 bit

Giá trị kiểu dữ liệu nằm ngoài phạm vi

Giá trị kiểu dữ liệu nằm ngoài phạm vi

Bất cứ khi nào bạn cố gắng thêm giá trị nằm ngoài phạm vi của kiểu dữ liệu. Trình biên dịch C sẽ đưa ra lỗi.
Đầu ra:

Lỗi phân đoạn

Lỗi phân đoạn xảy ra khi chương trình của bạn cố gắng truy cập vào một vùng bộ nhớ không được phép. Nói cách khác, lỗi này được đưa ra khi chương trình cố gắng truy cập vào bộ nhớ vượt quá không gian được phân bổ cho kiểu dữ liệu cụ thể.

Kiểu số nguyên (integer)

Kiểu số nguyên (integer data type) là một kiểu dữ liệu dùng để lưu trữ các giá trị số nguyên, tức là các số không có phần thập phân. C cung cấp nhiều loại số nguyên với kích thước và phạm vi khác nhau, vì vậy lập trình viên có thể dễ dàng lựa chọn kiểu dữ liệu phù hợp với yêu cầu về bộ nhớ và phạm vi số.

Dưới đây là các loại kiểu số nguyên trong C:

  • int (Số nguyên) Đây là kiểu số nguyên mặc định trong C.
  • short int (Số nguyên ngắn) Kiểu số nguyên có kích thước nhỏ hơn int, dùng để tiết kiệm bộ nhớ khi không cần lưu trữ các số lớn.
  • long int (Số nguyên dài) Kiểu số nguyên có kích thước lớn hơn int, dùng để lưu trữ các giá trị lớn hơn.
  • long long int (Số nguyên rất dài) Kiểu số nguyên có kích thước lớn hơn long int, thường dùng để lưu trữ các giá trị cực lớn.
  • signed và unsigned (Số nguyên có dấu và không dấu)
    - signed: Là kiểu mặc định, cho phép lưu trữ cả giá trị dương và âm.
    - unsigned: Chỉ lưu trữ giá trị dương, do đó phạm vi giá trị lớn hơn so với signed.

Kiểu số thực (float)

Kiểu số thực (floating-point data type) được dùng để lưu trữ các số có phần thập phân, bao gồm cả số dương và số âm. C cung cấp ba kiểu dữ liệu số thực chính là float, double, và long double. Những kiểu này khác nhau về kích thước bộ nhớ và độ chính xác.

Dưới đây là chi tiết về các kiểu số thực trong C:

float là kiểu số thực có độ chính xác đơn (single precision), phù hợp cho các ứng dụng yêu cầu tính toán đơn giản hoặc khi cần tối ưu hóa bộ nhớ..
double là kiểu số thực có độ chính xác kép (double precision) được sử dụng phổ biến hơn do độ chính xác cao hơn float và vẫn đảm bảo tính toán hiệu quả.
long double là kiểu số thực có độ chính xác lớn hơn kiểu double. Bạn có thể dùng trong các bài toán yêu cầu độ chính xác rất cao.

Kiểu Ký Tự

Kiểu ký tự (character data type) lưu trữ các ký tự đơn như chữ cái, chữ số hoặc các ký tự đặc biệt. Kiểu ký tự trong C được đại diện bởi kiểu dữ liệu char, có kích thước 1 byte và biểu diễn các ký tự ASCII.

char là kiểu dữ liệu dùng để lưu trữ một ký tự đơn.
Khi lưu trữ một ký tự trong biến kiểu char, thực tế là lưu trữ mã ASCII của ký tự đó. Bạn có thể in mã ASCII của ký tự bằng cách ép kiểu sang int.
Chuỗi ký tự trong C không phải là kiểu dữ liệu riêng biệt mà thực chất là một mảng các ký tự (char[]), với ký tự cuối cùng là ký tự null (\0), đánh dấu sự kết thúc của chuỗi.

  • Ký tự đặc biệt

Có các ký tự đặc biệt trong C được biểu diễn bằng cách sử dụng dấu \ (backslash). Một số ký tự phổ biến là:

\n: Xuống dòng.
\t: Tab ngang.
\': Dấu nháy đơn.
\": Dấu nháy kép.
\\: Dấu gạch chéo ngược.

Kiểu dữ liệu phái sinh (derived data types)

Trong ngôn ngữ lập trình C, kiểu dữ liệu phái sinh (derived data types) là các kiểu dữ liệu được tạo ra từ các kiểu dữ liệu cơ bản như int, char, float, và double. Các kiểu dữ liệu này bao gồm mảng, con trỏ, cấu trúc, hợp, và enum. Chúng giúp lập trình viên xử lý dữ liệu phức tạp hơn và xây dựng các cấu trúc dữ liệu linh hoạt.

Dưới đây là các kiểu dữ liệu phái sinh chính trong C:

Array (Mảng)

Mảng là tập hợp các phần tử có cùng kiểu dữ liệu được lưu trữ liên tiếp trong bộ nhớ. Mỗi phần tử của mảng được truy cập thông qua chỉ số (index), với chỉ số đầu tiên bắt đầu từ 0.

Pointer (Con trỏ)

Kiểu dữ liệu con trỏ được sử dụng để lưu trữ địa chỉ của một biến khác. Con trỏ có thể lưu trữ địa chỉ của các biến có bất kỳ kiểu dữ liệu nào. Con trỏ cho phép người dùng thực hiện phân bổ bộ nhớ động. Chúng cũng giúp truyền biến theo tham chiếu.

Con trỏ không có địa chỉ được gọi là con trỏ null. Con trỏ không có kiểu dữ liệu là con trỏ void. Nó được định nghĩa bằng cách sử dụng toán tử ‘*’.

Structure (Cấu trúc)

Đây là kiểu dữ liệu có thể lưu trữ các biến có kiểu dữ liệu tương tự hoặc khác nhau. Ví dụ, chúng ta có thể sử dụng cấu trúc để lưu trữ thông tin về một nhân viên, chẳng hạn như tên nhân viên, ID nhân viên, lương, ... Hồ sơ của mỗi nhân viên sẽ được biểu diễn bằng một đối tượng của cấu trúc. Kích thước của cấu trúc là tổng kích thước lưu trữ mà mỗi biến yêu cầu. Từ khóa 'struct' định nghĩa một cấu trúc.

Union (Hợp)

Union tương tự như cấu trúc nhưng khác ở chỗ, các thành viên của một union chia sẻ cùng một vùng nhớ, tức là chỉ một thành viên có thể lưu trữ giá trị tại một thời điểm.

Theo một cách giải thích khác, union là một nhóm các phần tử có kiểu dữ liệu giống nhau hoặc khác nhau. Trong một union, vị trí bộ nhớ là giống nhau cho tất cả các phần tử. Kích thước của nó sẽ bằng với bộ nhớ cần thiết cho kiểu dữ liệu lớn nhất được xác định. Chúng ta sử dụng từ khóa 'union' để xác định một union. Bạn có thể khai báo nhiều biến. Tuy nhiên, chỉ một biến có thể lưu trữ giá trị tại một thời điểm.

Kiểu dữ liệu liệt kê

Kiểu dữ liệu liệt kê được sử dụng để định nghĩa các biến chỉ có thể gán một số giá trị số nguyên rời rạc trong chương trình. Chúng được sử dụng để làm cho chương trình dễ đọc hơn, linh hoạt hơn và dễ bảo trì hơn. Chúng ta sử dụng từ khóa 'enum' để khai báo các kiểu liệt kê mới trong ngôn ngữ lập trình C.

Cú pháp enum:

enum flag {const1, const2, const3………};

Void

Void chỉ là một kiểu dữ liệu rỗng biểu thị rằng không có giá trị nào khả dụng. Thông thường, void được sử dụng cho các hàm. Khi chúng ta khai báo một hàm là void, nó không phải trả về bất cứ thứ gì.

Void được sử dụng trong ba trường hợp:

  • Hàm trả về là void – Một hàm không có giá trị trả về sẽ có kiểu trả về là void.
  • Đối số hàm là void – Một hàm không có tham số có thể chấp nhận void.
  • Con trỏ đến void – Nó biểu thị địa chỉ của một đối tượng, nhưng không phải kiểu của đối tượng đó.

Kết luận

Trong bài viết này, chúng ta đã tìm hiểu về các kiểu dữ liệu khác nhau trong C. Việc nắm vững các kiểu dữ liệu trong C là nền tảng vững chắc để tiếp cận các khái niệm lập trình cao cấp hơn. TechWorks hy vọng những thông tin trên sẽ giúp bạn tạo các chương trình hiệu quả trong lập trình C.

Bài viết liên quan

JavaFX là gì? - Kiến thức chi tiết từ A - Z về JavaFX
JavaFX là một framework mạnh mẽ để xây dựng các ứng dụng desktop và ứng dụng internet phong phú (RIA) bằng Java. Được thiết kế như một thế hệ kế tiếp của Swing, JavaFX cung cấp một bộ công cụ hiện đại để tạo ra giao diện người dùng trực quan và tương tác.
Sự khác biệt giữa JDK, JRE và JVM trong Java là gì?
Trong số các ngôn ngữ lập trình, Java hiện là ngôn ngữ phổ biến nhất được sử dụng cho các mục đích phát triển. Phần lớn các lập trình viên sử dụng Java để phát triển ứng dụng di động, máy tính để bàn, phát triển game, lập trình back-end, ... Trong quá trình phát triển với Java, JVM, JRE, và JDK đã và đang đóng góp những vai trò vô cùng quan trọng.
JDK là gì? Giới thiệu về Java Development Kit
Khi xây dựng các ứng dụng phần mềm trên Java, JDK có trách nhiệm đẩy nhanh quá trình phát triển và đơn giản hóa dự án. Cùng với JVM (Java Virtual Machine) và JRE (Java Runtime Environment), JDK là một trong những công nghệ cốt lõi được sử dụng trong lập trình Java.
9