Ràng buộc
Ràng buộc (constraint) khoảng giá trị cho các kiểu số nguyên rất có ích cho việc loại trừ sai sót trong chương trình. Thí dụ, nếu biết trước rằng trong chương trình không bao giờ có nhiều hơn 50 bác sĩ và 1000 giường bệnh và nếu muốn loại trừ số lượng âm, ta làm như sau.
Code: type so_bac_si is new Integer range 0..50;
type so_giuong_benh is new Integer range 0..1000;
Nhờ đó bộ biên dịch sẽ phát hiện lỗi trong câu lệnh sau đây.
Code:
Tất nhiên bộ biên dịch có khả năng phân tích tuyệt vời nhất vẫn không phải là đấng toàn năng để phát hiện ra mọi lỗi ngay từ khi biên dịch. Nhưng trường hợp không thể phát hiện lỗi nó sẽ sinh mã đích kiểm tra. Khi thi hành chương trình, trong phép đổi kiểu, giá trị biến được kiểm tra và nếu giá trị phá ràng buộc thì chương trình sẽ gây ra ngoại lệ (
Constraint_Error). Thí dụ, đoạn mã sau đây chỉ thi hành được khi n_giuong_benh không vượt quá 50.
Code: n_bac_si := So_bac_si(n_giuong_benh); -- có thể gây ngoại lệ Constraint_Error
Thí dụ với số bác sĩ và số giường bệnh rất rõ ràng nhưng hơi thiếu thực tế. Vì vậy xin nêu thêm một thí dụ nữa trình diễn các kiểu số nguyên xác lập sẵn theo chuẩn Ada. Ngoài kiểu ra, ta sẽ đưa vào thí dụ một tiết mục đặc biệt của Ada:
phân kiểu (subtype).
Code: type Integer is range -2**31 .. 2**31-1;
subtype Natural is Integer range 0 .. 2**31-1; -- so tự nhiên, bao gồm cả số 0.
subtype Positive is Integer range 1 .. 2**31-1; -- số dương
Các phân kiểu sẽ có ích ở nơi ta cần ràng buộc một khoảng giá trị thuộc một kiểu nào đó, nhưng lại không muốn đặt ra kiểu mới. Mọi biến thuộc một kiểu nào đó, dẫu có phân kiểu khác nhau vẫn có thể gán trị cho nhau mà không cần phải đổi kiểu tường minh. Mã đích đương nhiên vẫn thường xuyên kiểm tra giá trị và gây ngoại lệ cho trường hợp một giá trị nào đó định phá ràng buộc.
Nếu giờ ta cần một danh sách liên kết (linked list) chẳng hạn thì ta không bao giờ khai báo biến n_elements (số phần tử) là Integer, mà nên dùng Natural. Nhờ đó ta đưa được thêm thông tin vào mã nguồn và giảm được khả năng lầm lỗi. Sẽ không bao giờ số phần tử giảm xuống dưới 0. Sẽ không bao giờ việc nhặt phần tử khỏi danh sách rỗng có thể thi hành. Đây là một thí dụ lấy từ thực tế, khi bộ biên dịch đã báo một lỗi mà ở ngôn ngữ C mọi chuyện có thể kết thúc bằng một
Access Violation hay
Segmentation Fault thật hoạt kê. Mà chuyện đó cũng có thể chẳng hoạt kê chút nào khi thay vì có thể đi ngủ lúc 11 giờ đêm ta phải thức đến 3 giờ sáng để tìm rối và gỡ rối
.
Xin nói thêm, Ada cho phép xác lập ràng buộc khoảng trên cả các kiểu số
dấu chấm động (floating-point), số
dấu chấm tĩnh (fixed-point) và số
dấu chấm tĩnh thập phân (decimal). Thí dụ:
Code: -- Số dấu chấm động:
type Real is digits 10; -- không ràng buộc
type He_so is digits 8 range -1.0 .. 1.0; -- có ràng buộc
type Khoi_luong is digits 7 range 0.0 .. 1.0E35;
type Goc is new Real range 0.0 .. 2.0 * pi;
subtype Xac_suat is Real range 0.0 .. 1.0; -- có ràng buộc
-- Số dấu chấm tĩnh:
type Volt is delta 0.125 range 0.0 .. 255.0; -- có ràng buộc
type Fraction is delta System.Fine_Delta range -1.0 .. 1.0;
-- Fraction’First = 0.0
-- Fraction’Last = 1.0 – System.Fine_Delta
-- Số dấu chấm tĩnh thập phân:
type Money is delta 0.01 digits 18; -- có ràng buộc
-- Money’First = -10.0**16 + 0.01
-- Money’Last = 10.0**16 – 0.01
subtype Salary is Money digits 10; -- có ràng buộc
-- Salary’First = -10.0**8 + 0.01
-- Salary’Last = 10.0**8 – 0.01