Dự án: Một máy tính xác nhận đầu vào
Liên kết đầu vào, kiểm tra giới hạn, chức năng và mã thoát.
Wave Foundation
Mục tiêu và hành động
Nhập số lượng, đơn giá và tính tổng. Nhập hai số nguyên cách nhau bằng dấu cách hoặc ngắt dòng. Ví dụ này chỉ chấp nhận số lượng từ 1 đến 1000 và đơn giá từ 0 đến 100000 nên được tính trong phạm vi nhân i32.
Lưu nó vào main.wave, chạy wavec run main.wave, sau đó nhập 3 1200. Kết quả đầu ra của chương trình như sau. Khả năng hiển thị của các ký tự được nhập trong thiết bị đầu cuối tách biệt với đầu ra của chương trình.
fun total(quantity: i32, price: i32) -> i32 {
return quantity * price;
}
fun main() -> i32 {
var quantity: i32 = 0;
var price: i32 = 0;
input("{} {}", quantity, price);
if (quantity < 1 || quantity > 1000 || price < 0 || price > 100000) {
println("out of range");
return 1;
}
println("total={}", total(quantity, price));
return 0;
}
Kết quả thực hiện:
total=3600
Đồng thời kiểm tra lỗi
Nếu bạn đặt 0 1200, nó sẽ yêu cầu out of range và mã thoát 1. Lỗi phân tích số trong input và việc kiểm tra phạm vi công việc của chương trình là hai bước khác nhau. Mã thông báo/loại không phải số vượt quá phạm vi/trước khi yêu cầu đầu vào EOF là lỗi đầu vào. Đầu vào tích hợp này không phải là giao diện trả về lỗi và yêu cầu nhập lại. Nếu bạn cần một trình phân tích cú pháp có thể phục hồi, hãy tự định cấu hình quy trình xác minh bằng cách đọc byte bằng io.
Bài tập và bình luận mở rộng
Lấy tỷ lệ chiết khấu làm đầu vào thứ ba và kiểm tra xem nó có phải là 0 đến 100 hay không. Để tránh các phép nhân trung gian lớn, bạn cần mở rộng phạm vi tính toán bằng i64 và kiểm tra phạm vi khi thu hẹp kết quả. Nếu bạn chỉ mở rộng loại kết quả cuối cùng, các phép tính trung gian có thể đã được thực hiện trên loại hẹp.
Bảng điều khiển I/O · Tiếp theo: Đọc tệp
Tại sao phải quyết định phạm vi tính toán trước?
Đầu vào lớn nhất là số lượng 1000 và đơn giá 100000. Nhân hai giá trị là 100000000 nên nằm trong khoảng i32. Việc kiểm tra phạm vi này là cần thiết để có thể sử dụng kết quả nhân của hàm total.
main, nhận đầu vào, chịu trách nhiệm về thông báo đầu vào và lỗi, còn total chỉ chịu trách nhiệm tính toán. Ngay cả khi sau này bạn chuyển sang đọc lệnh từ tệp, bạn vẫn có thể sử dụng chức năng tính toán.
Tính toán chiết khấu hoàn chỉnh
Bạn có thể nhân tổng số tiền với 100 bằng cách cộng phần trăm chiết khấu. Chuyển đổi để thực hiện các phép tính trung gian dưới dạng i64 rồi áp dụng tỷ lệ chiết khấu. Vì phần phân số của phép chia số nguyên bị loại bỏ nên ví dụ này sẽ cắt bớt số tiền sau khi chiết khấu thành số nguyên.
fun discounted_total(quantity: i32, price: i32, discount: i32) -> i64 {
var subtotal: i64 = (quantity as i64) * (price as i64);
var remaining: i64 = 100 - (discount as i64);
return subtotal * remaining / 100;
}
fun main() -> i32 {
var quantity: i32 = 0;
var price: i32 = 0;
var discount: i32 = 0;
input("{} {} {}", quantity, price, discount);
if (quantity < 1 || quantity > 1000) {
println("invalid quantity");
return 1;
}
if (price < 0 || price > 100000) {
println("invalid price");
return 2;
}
if (discount < 0 || discount > 100) {
println("invalid discount");
return 3;
}
println("total={}", discounted_total(quantity, price, discount));
return 0;
}
Kết quả thực hiện:
total=3240
Kết quả trên là khi nhập 3 1200 10. Đầu ra là 3240, được trừ 10% so với tổng số 3600 ban đầu.
| đầu vào | kết quả mong đợi | đường dẫn để kiểm tra |
|---|---|---|
3 1200 0 |
total=3600 |
không giảm giá |
3 1200 100 |
total=0 |
Giảm giá đầy đủ |
3 1200 101 |
invalid discount |
Tỷ lệ chiết khấu vượt quá phạm vi |
1000 100000 0 |
total=100000000 |
đầu vào tối đa |
0 1200 10 |
invalid quantity |
Số lượng dưới phạm vi |
bài tập tiếp theo
Hãy thử thay đổi hàm thành số thập phân làm tròn. Trong chương trình chỉ chấp nhận số dương này, việc cộng 50 trước khi chia cho 100 sẽ làm tròn thành số nguyên. Khi bạn nhập 99 cho 1 và tỷ lệ chiết khấu là 50, bạn có thể so sánh kết quả cắt của 49 và kết quả làm tròn của 50.