2012-01-30 33 views
9

Tôi đang trong quá trình viết một ngôn ngữ kịch bản và tôi muốn sao chép (khá tốt chuẩn) C order of operations.Các nhánh của liên kết từ phải sang trái và từ trái sang phải trong ngôn ngữ dựa trên C là gì?

Một điều mà tôi chưa bao giờ có một nắm vững là một khái niệm chính thức mặc dù là associativity. Tại sao một số nhóm nhà điều hành từ trái sang phải và các nhóm khác từ phải sang trái?

Ai đó có thể cho tôi một vài ví dụ về cách một dòng mã có thể trông khác nếu các quy tắc là tất cả từ trái sang phải hoặc ngược lại với những gì chúng là? Hoặc tại sao sự kết hợp lại là con đường của nó, vì dường như tôi chỉ là một sự lựa chọn tùy ý, nhưng tôi cho rằng họ có lý do cho nó.

Ngoài ra, chỉ cần lưu ý, tôi biết những gì có nghĩa associativity, tôi chỉ không thể nghĩ ra bất kỳ ví dụ nơi trái sang phải (hoặc ngược lại) là tốt hơn so với các lựa chọn khác

+0

Đây là một câu hỏi tuyệt vời! Ngoài ra, hãy xem [lý do tại sao-giao-chuyển-toán-gán-sang-bên-trái-tay] (http://programmers.stackexchange.com/questions/98406/why-does-the-assignment-operator- giao cho bên trái) – nawfal

Trả lời

13

Đối với hầu hết các phần, mỗi toán tử có tính kết hợp phù hợp nhất với toán tử đó.

Tất cả toán tử nhị phân không gán đều có liên kết từ trái qua phải. Điều này rất hữu ích vì lý do rõ ràng là tiếng Anh được đọc từ trái sang phải và do đó việc đánh giá x + y + z phù hợp với cách đọc. Ngoài ra, đối với toán tử số học, ngữ nghĩa khớp với những gì chúng ta mong đợi từ việc sử dụng toán tử trong toán học.

Toán tử gán có liên kết từ phải sang trái. Chuyển nhượng từ trái sang phải sẽ có ngữ nghĩa kỳ lạ và bất ngờ. Ví dụ: x = y = z sẽ dẫn đến x có giá trị ban đầu là yy có giá trị ban đầu là z. Dự kiến ​​cả ba biến sẽ có cùng giá trị sau khi biểu thức hoàn tất.

Tiền tố khai thác unary có associativity từ phải sang trái, có ý nghĩa bởi vì các nhà khai thác gần gũi nhất với các toán hạng được đánh giá đầu tiên, vì vậy trong ~!x, !x được đánh giá đầu tiên, sau đó ~ được áp dụng cho kết quả.Thực tế, thực sự là là toán tử tiền tố được áp dụng với tính tương hợp từ trái sang phải: để nói rằng ~!x có nghĩa là đánh giá ~x và sau đó áp dụng ! cho kết quả là hoàn toàn trái ngược với cách chúng ta suy nghĩ về biểu thức (hoặc ít nhất) , làm thế nào hầu hết mọi người nghĩ về biểu thức ...).

+1

Trong C, sự kết hợp từ trái qua phải của toán tử gán sẽ làm cho 'x = y = z' một lỗi (với cùng lý do là' (x = y) = z' là một lỗi). – caf

+0

@caf: Đúng, nhưng nếu một người đang cân nhắc việc thay đổi tính kết hợp của toán tử, người ta cũng có thể xem xét việc thay đổi danh mục giá trị của biểu thức toán tử. –

0

lũy roundoff thường là câu trả lời.

Tuy nhiên, >> và < < phải là cách chúng hoặc cấu trúc như 12 < < 2 >> 3 không hoạt động.

6

Ví dụ:

5 - 4 - 3 
(5 - 4) - 3 = -2 // left association is correct 
5 - (4 - 3) = 4 // right is incorrect 

a == b == c // What does this equal? 
      // It is common to have == be non-associative because of this. 

x = y = z 
x = (y = z) // right association is correct, sets x and y 
(x = y) = z // left is incorrect, does not set y 

Hầu hết các nhà khai thác kế thừa associativity của họ từ toán học. Bitwise có thể được xem như toán tử số học và do đó đã để lại kết hợp.

unary là kết hợp đúng vì nó nhóm theo cách đó:

~!-x = ~(!(-(x))) 

Một cách khác sẽ không có ý nghĩa nhiều trừ khi postfix.

+1

Tôi không thích không kết hợp. Theo tôi, 'a == b == c' có nghĩa là' (a == b) == c' (so sánh kết quả Boolean của 'a == b' với' c') hoặc được đặt biệt như trong Python để 'let b '= b trong (a == b') && (b '== c)'. –

2

Toán tử phức tạp là lũy thừa (ví dụ: ** trong python,^trong R, haskell). Hầu hết các ngôn ngữ, trình phân tích cú pháp, v.v. xem 3 ** 3 ** 33 ** (3 ** 3). Cá nhân tôi nghĩ đây là giải thích chính xác, nhưng gần đây đã nhận thấy rằng cả quãng tám và matlab tính toán điều này là (3 ** 3) ** 3.

Đây không phải là vấn đề trong C vì nó không có toán tử lũy thừa. Thay vào đó, bạn thực hiện cuộc gọi đến hàm pow và phải nêu rõ pow(3,pow(3,3)) hoặc pow(pow(3,3),3).

+2

Nó là đúng liên kết trong Cobol là tốt, và tại Fortran: http://www.fortran.com/F77_std/rjcnf0001-sh-6.html. Về mặt toán học, đây là cách giải thích chính xác. – EJP

Các vấn đề liên quan