Phạm vi giá trị các kiểu dữ liệu trong C/C++

Phạm vi giá trị các kiểu dữ liệu trong C/C++ là một vấn đề mà rất ít bạn quan tâm. Nhưng đây lại là một kiến thức rất quan trọng mà các lập trình viên nên biết. Không biết các bạn đã nghe tới vấn đề bị “tràn số” hay chưa. Để tránh bị lỗi tràn số, các bạn cần biết phạm vi giá trị các kiểu dữ liệu trong ngôn ngữ lập trình.

Lỗi tràn số trong lập trình

Tràn số là hiện tượng biến được gán giá trị nằm ngoài khoảng giá trị thuộc phạm vi của kiểu dữ liệu của biến đó. Đây là một lỗi khá phổ biến đối với các bạn mới học lập trình. Hình ảnh dưới đây mang tính chất mình họa cho lỗi này.

Tràn số trong lập trình - Nguyễn Văn Hiếu Blog
Hiện tượng tràn số trong lập trình(Overflow)

Để giúp các bạn chưa biết về hiện tượng tràn số, mình sẽ lấy ví dụ code C++ với kiểu dữ liệu char. Chắc nhiều bạn đã biết char có kích thước 1 byte = 8 bits. Tức có thể biểu diễn 28 giá trị khác nhau. Ta lại chia đôi 2 miền âm dương ra. Tức là từ -27 đến 27 – 1. Bởi vì phía bên nửa dương cần biểu diễn cho cả số 0 nữa.

Ví dụ về lỗi tràn số

Mình xin 5 phút quảng cáo nha =))

Các bạn nghĩ chương trình này sẽ in ra gì? Vòng for kia sẽ lặp bao nhiêu lần?

Với s = 97, mình sẽ in ra được số 97 nếu ép kiểu về int, nếu không sẽ in ra chữ ‘a’. Do mã ASCII của a = 97.

Quay lại với câu hỏi trên. Đáp án là vòng lặp này sẽ lặp vô tận. Vì giá trị lớn nhất của char là 127. Khi nó nhận giá trị từ 128 trở lên, sẽ xảy ra hiện tượng tràn số.

Nếu không tin, bạn hãy chạy thử. Hoặc đơn giản hơn, thử mấy dòng code này coi nó in ra gì:

Đây là output bạn nhận được. Đó là hậu quả do tràn số gây ra.

Chú ý: Hiện tượng tràn số có thể xảy ra ở tất cả các ngôn ngữ lập trình. Với các ngôn ngữ lập trình bậc cao, bản thân nó đã có cơ chế kiểm soát nên có thể bạn không thấy.

Nếu bạn đang quan tâm tới lập trình C/C++, hãy đọc các bài viết hay khác tại chuyên mục lập trình C/C++.

Phạm vi giá trị các kiểu dữ liệu trong C/C++

Phạm vi giá trị các kiểu dữ liệu
Phạm vi giá trị các kiểu dữ liệu

Vậy làm gì để tránh bị tràn số trong lập trình nói chung? Bạn cần phải nắm được phạm vi giá trị các kiểu dữ liệu trong mỗi ngôn ngữ lập trình. Về cơ bản nhiều kiểu dữ liệu trong các ngôn ngữ lập trình là giống nhau. Do vậy, trong bài viết này, mình chỉ trình bày về phạm vi giá trị các kiểu dữ liệu trong C/C++.

Bảng phạm vi giá trị các kiểu dữ liệu trong C/C++

Để xem phạm vi của các kiểu dữ liệu này, bạn có thể sử dụng các Marco ở bảng trên. Dưới đây là code ví dụ:

Output:

Giải thích phạm vi của kiểu dữ liệu

Mình sẽ lấy ví dụ với kiểu char cho nhỏ nhé. Mình cần các bạn biết về hoán vị nữa.

Như các bạn biết, 1 bit trong lập trình sẽ biểu diễn được 2 giá trị: 0 hoặc 1. Tức là biểu diễn được 21 giá trị.

Vậy 2 bits sẽ biểu diễn được 4 giá trị: 00, 01, 10 và 11. Tức là biểu diễn được 22 giá trị.

Như vậy, 1 byte = 8 bits sẽ biểu diễn được 28 giá trị khác nhau.

Mà máy tính lưu giá trị mã bit 0 và 1. Tức dạng nhị phân. Do đó 00 = 0, 01 = 1, 10 = 2, 11 = 3 trong cơ số 10. Như vậy, giá trị lớn nhất mà 1 byte có thể biểu diễn là 11111111 = 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 = 255.

Đó là lý do kiểu unsigned char có phạm vi giá trị từ 0 đến 255. Còn kiểu char do có cả miền âm nên sẽ bị chia đôi(-128 đến 127). Phần dương bị hụt 1 giá trị do cần biểu diễn cả số 0.

Kết luận

Như vậy, trong bài viết này Nguyễn Văn Hiếu đã giúp các bạn biết được phạm vi giá trị các kiểu dữ liệu trong ngôn ngữ C++. Đồng thời, các bạn cũng đã biết về hiện tượng tràn số và cách để tránh bị tràn số. Còn nếu bạn nào chưa biết cách thì để lại câu hỏi ở bình luận nhé.

Chúc các bạn học tập tốt!

Tài liệu tham khảo

[1]. https://www.geeksforgeeks.org/data-type-ranges-and-their-macros-in-c/

avatar
  Subscribe  
newest oldest most voted
Notify of
quân
Guest
quân

Thầy cho em hỏi là kiểu int và kiểu long int có phạm vi giá trị giống nhau. Vậy hai kiểu này khác nhau điều gì?

Thanh Bình
Guest
Thanh Bình

– Bạn cho mình hỏi: kiểu long long và double điều là 8 byte ….. vậy thì tại sao miền giá trị của double lại lớn hơn vậy ạ?