Nhóm với dấu ngoặc đơn
Trong các phần trước, chúng ta đã thấy nhiều lần rằng một số biểu thức có thể gây ra kết quả không mong muốn do thứ tự ưu tiên của các phép toán. Để thay đổi rõ ràng thứ tự tính toán, chúng ta nên sử dụng dấu ngoặc đơn. Một phần của biểu thức được bao quanh bởi chúng có mức ưu tiên cao hơn so với môi trường, mà không cần quan tâm đến các mức ưu tiên mặc định. Các cặp dấu ngoặc đơn có thể được lồng vào nhau, nhưng không nên tạo nhiều hơn 3-4 mức lồng nhau. Tốt hơn là chia các biểu thức quá phức tạp thành nhiều biểu thức đơn giản hơn.
Script ExprParentheses.mq5
cho thấy sự tiến hóa của việc đặt dấu ngoặc đơn trong một biểu thức. Mục đích ban đầu của nó là đặt bit trong cờ biến bằng cách sử dụng thao tác dịch trái <<
. Số bit được lấy từ độ lệch biến nếu nó không bằng không, hoặc nếu không, là 1 (hãy nhớ rằng việc đánh số bắt đầu bằng không). Sau đó, giá trị thu được được nhân với hệ số. Không cần phải tìm kiếm bất kỳ ý nghĩa áp dụng nào trong ví dụ này. Tuy nhiên, các cấu trúc phức tạp hơn cũng có thể xảy ra.
int offset = 8;
int coefficient = 10, flags = 0;
int result1 = coefficient * flags | 1 << offset > 0 ? offset : 1; // 8
int result2 = coefficient * flags | 1 << (offset > 0 ? offset : 1); // 256
int result3 = coefficient * (flags | 1 << (offset > 0 ? offset : 1)); // 2560
2
3
4
5
Phiên bản đầu tiên, không có dấu ngoặc đơn, có vẻ đáng ngờ ngay cả với trình biên dịch. Nó đưa ra cảnh báo mà chúng ta đã biết: "biểu thức không phải boolean". Vấn đề là toán tử điều kiện ba ngôi có mức ưu tiên thấp nhất trong tất cả các toán tử ở đây. Vì lý do này, toàn bộ phần bên trái trước ?
được coi là điều kiện của nó. Bên trong điều kiện, các phép tính theo thứ tự sau: Phép nhân, dịch chuyển bit, so sánh "nhiều hơn" và OR bit, cho kết quả là một số nguyên. Tất nhiên, nó có thể được sử dụng là true
hoặc false
, nhưng mong muốn "truyền đạt" những ý định như vậy đến trình biên dịch bằng cách sử dụng ép kiểu rõ ràng . Nếu không có nó, trình biên dịch coi biểu thức là đáng ngờ, và không phải vô ích. Phép tính đầu tiên cho kết quả là 8. Nó không đúng.
Chúng ta hãy thêm dấu ngoặc đơn quanh toán tử ba ngôi. Cảnh báo của trình biên dịch sẽ biến mất. Tuy nhiên, biểu thức vẫn được tính toán sai. Vì mức độ ưu tiên của phép nhân cao hơn so với phép OR bitwise, nên các biến coefficient
và flags
được nhân trước khi sử dụng mặt nạ bit, thu được bằng cách dịch chuyển sang trái. Kết quả là 256
.
Cuối cùng, thêm một cặp dấu ngoặc đơn nữa, ta sẽ có được kết quả chính xác: 2560
.