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ố

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/

12 COMMENTS

    • Số thì làm gì có bit hả em, chỉ có kiểu dữ liệu có size là bao nhiêu (byte/bit) thôi nhé,

    • Không có kiểu dữ liệu nào có size 10 bits cả, đơn vị của nó là bytes, mà là bytes thì phải là bội của 8

  1. e muốn in ra tổng của 2 số là 1 số có 40 chữ số thì phải sử dụng mạng, cụ thể là dùng như thế nào ạ

    • ý tưởng như cách em cộng trên giấy thôi, cộng từng chữ số từ cuối lên.
      Nếu khởi đầu hai số không cùng số lượng em có thể thêm số 0 vào đầu cho bằng nhau.

      Em cũng nên search “cộng số nguyên lớn trong C” nhé

  2. dạ thầy cho em hỏi một số mình biểu diễn nằm dài quá kiểu long long int thì mình biểu diễn như thế nào ạ
    với cách mình sài 2 biến int để biểu diễn một số. có lm được cách đó ko ạ. em cảm ơn ạ

    • Nếu là C/C++ bạn phải cài đặt bignumber, bạn search số nguyên lớn trong C, dựa trên chuỗi hoặc array để cài.

      Còn ngôn ngữ bậc cao như java hay c# python thì nó có sẵn thư viện rồi

  3. – 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 ạ?

    • Bạn xem kỹ lại nhé, là 2.22507 x e ^ 308
      long long chắc chắn lưu được range rộng hơn vì nó không có phần thực.

  4. 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ì?

LEAVE A REPLY

Please enter your comment!
Please enter your name here