Tính liên kết của các toán tử là gì và tại sao nó lại quan trọng?


88

Tính liên kết (đối với một toán tử) là gì và tại sao nó lại quan trọng?

Đã cập nhật: liên kết toán tử


2
Kiểu liên tưởng nào? Tính liên kết của nhà điều hành?
Ikke

26
@Neil Butterworth - Đó là một nhận xét đặc biệt gay gắt cho những gì có vẻ như là một câu hỏi hợp lý. Toàn bộ điểm của trang web là trở thành một kho lưu trữ trung tâm cho TẤT CẢ kiến ​​thức lập trình bao gồm những thứ được đề cập trong các văn bản giới thiệu. Đối với việc bạn nhận xét về việc @Jian Lin trả lời bình luận của riêng anh ấy, điều đó cũng có thể chấp nhận được như đã trình bày trong câu hỏi đầu tiên của Câu hỏi thường gặp chính thức. Ai đó có cấp đại diện của bạn nên biết rõ hơn. Nếu bạn không đồng ý với nó, ít nhất hãy cư xử với nó.
Rob Allen

1
@Rob Allen Xem các bài viết khác của anh ấy. Ngoài ra, tôi không nói rằng anh ấy không nên trả lời bài đăng của chính mình, chỉ là nó không hữu ích. Và tôi sẽ làm cho bạn một thỏa thuận - Tôi sẽ không cho bạn biết cách cụm từ các bài đăng của bạn ở đây nếu bạn không cho tôi biết cách cụm từ của tôi.

Câu trả lời:


105

Đối với toán tử, tính kết hợp có nghĩa là khi cùng một toán tử xuất hiện trong một hàng, thì toán tử nào sẽ xuất hiện trước tiên chúng ta áp dụng. Trong phần sau, hãy Qlà nhà điều hành

a Q b Q c

Nếu Qđược để là liên kết, thì nó đánh giá là

(a Q b) Q c

Và nếu nó là liên kết phù hợp, thì nó sẽ đánh giá là

a Q (b Q c)

Nó quan trọng, vì nó thay đổi ý nghĩa của một biểu thức. Hãy xem xét toán tử chia với số học nguyên, được kết hợp trái

4 / 2 / 3    <=>    (4 / 2) / 3    <=> 2 / 3     = 0

Nếu nó là liên kết đúng, nó sẽ đánh giá thành một biểu thức không xác định, vì bạn sẽ chia cho 0

4 / 2 / 3    <=>    4 / (2 / 3)    <=> 4 / 0     = undefined

bạn có biết làm thế nào để tìm ra sự kết hợp cho dù nó là trái hay phải đối với máy cắt đã cho?
dùng2510115

1
Ví dụ expr -> expr + term;là liên kết trái và expr -> term + exprliên kết phải.
Subin Sebastian

15
Trong dòng đầu tiên của câu trả lời của bạn, thay vì "khi cùng một toán tử xuất hiện" thì thích hợp hơn để nói "khi các toán tử có cùng mức độ ưu tiên xuất hiện". Ví dụ: a * b / c => trong đó * và / có cùng mức độ ưu tiên.
1O1

2
@ 1O1 cảm ơn, nhưng điều gì sẽ xảy ra nếu những toán tử có cùng mức độ ưu tiên đó có sự kết hợp khác nhau? Làm thế nào để a * b / cđánh giá nếu *sẽ là liên kết bên trái nhưng /sẽ là liên kết bên phải? Sau đó, có một mâu thuẫn. Vì vậy, tôi nghĩ người ta cần nói "khi các toán tử có cùng mức độ ưu tiên và tính liên kết" nếu bạn muốn bao gồm nhiều toán tử.
Johannes Schaub - litb

2
@Mark tôi không biết, nhưng tôi không thể nghĩ về cách nó sẽ hoạt động. Có lẽ đáng để thêm một câu hỏi về stackoverflow
Johannes Schaub - litb

13

Có ba loại liên kết:

Tính chất liên kết trong toán học

Thứ tự hoạt động trong ngôn ngữ lập trình

Tính liên kết trong bộ nhớ đệm của CPU.

Thuộc tính liên kết trong toán học là thuộc tính của các toán tử như phép cộng (+). Thuộc tính này cho phép bạn sắp xếp lại các dấu ngoặc đơn mà không làm thay đổi giá trị của một câu lệnh, tức là:

(a + b) + c = a + (b + c)

Trong ngôn ngữ lập trình, tính liên kết (hoặc tính cố định) của một toán tử là một thuộc tính xác định cách các toán tử có cùng mức độ ưu tiên được nhóm lại khi không có dấu ngoặc đơn; tức là mỗi toán tử được đánh giá theo thứ tự nào. Điều này có thể khác nhau giữa các ngôn ngữ lập trình.

Trong bộ nhớ đệm của CPU, tính liên kết là một phương pháp tối ưu hóa hiệu suất.


3
các associativity (hoặc tính cố định) của một nhà điều hành là một tài sản mà xác định cách điều hành của các ưu tiên tương tự được nhóm lại trong sự vắng mặt của dấu ngoặc đơn - cụm từ đó chỉ là hoàn hảo để làm cho tôi hiểu
Rafael Eyng

7

Đơn giản!!

Left Associative means we evaluate our expression from left to right

Right Associative means we evaluate our expression from right to left 

Chúng tôi biết *, / và% có cùng mức độ ưu tiên, nhưng theo tính liên kết, câu trả lời có thể thay đổi:

Ví dụ: Chúng ta có biểu thức: 4 * 8/2% 5

Left associative:   (4 * 8) / 2 % 5 ==> (32 / 2) % 5 ==> 16 % 5 ==> 1

Right associative:  4 * 8 /(2 % 5) ==>  4 * ( 8 / 2) ==> 4 * 4 ==> 16

2
Có vẻ như có một lỗi trong câu trả lời: 2 % 5đánh giá thành 2, không 0.
6005

5

Nếu bạn đang đề cập đến "tính liên kết toán tử" - đó là cách một ngôn ngữ xác định cách các toán tử có cùng mức độ ưu tiên được nhóm lại mà không có dấu ngoặc đơn.

Ví dụ, các toán tử + và - trong các ngôn ngữ dựa trên C có cùng mức độ ưu tiên. Khi bạn viết một biểu thức sử dụng cả hai (không có dấu ngoặc đơn), trình biên dịch phải xác định thứ tự để đánh giá chúng theo thứ tự nào.

Nếu bạn viết 12 - 5 + 3, các đánh giá có thể bao gồm:

  1. (12 - 5) + 3 = 10
  2. 12 - (5 + 3) = 4

Tùy thuộc vào thứ tự bạn đánh giá biểu thức, bạn có thể nhận được các kết quả khác nhau. Trong các ngôn ngữ dựa trên C, + và - đã để lại tính kết hợp, có nghĩa là biểu thức ở trên sẽ được đánh giá là trường hợp đầu tiên.

Tất cả các ngôn ngữ đều có các quy tắc được xác định rõ ràng cho cả mức độ ưu tiên và tính liên kết. Bạn có thể tìm hiểu thêm về các quy tắc cho C # tại đây. Các khái niệm chung về tính liên kết của toán tử và mức độ ưu tiên được đề cập kỹ trên wikipedia.


Các ví dụ của bạn sẽ rõ ràng hơn nếu tất cả chúng đều sử dụng các toán hạng giống nhau.
Michael Carman

Điều gì sẽ xảy ra nếu hai toán tử có cùng thứ tự ưu tiên xuất hiện trong một biểu thức không có ẩn số, nhưng một trong số chúng có phép kết hợp trái và toán tử kia có quyền? Nó sẽ chỉ sử dụng tính liên kết của toán tử nào mà nó tìm thấy đầu tiên?
Hector

nó không thể xảy ra như cùng một tiền lệ có nghĩa là cùng một sự kết hợp. nếu đây không phải là trường hợp thì đó có thể là những mơ hồ đe dọa chính sự tồn tại của thực tế.
Ankur S

5

nó là thứ tự đánh giá cho các toán tử có cùng mức độ ưu tiên. Thứ tự TRÁI PHẢI hoặc PHẢI TRÁI đều quan trọng. Đối với

3 - 2 - 1

nếu nó là TRÁI sang PHẢI, thì nó là

(3 - 2) - 1

và bằng 0. Nếu nó PHẢI sang TRÁI, thì nó là

3 - (2 - 1)

và nó là 2. Trong hầu hết các ngôn ngữ, chúng ta nói rằng toán tử trừ có phép kết hợp TRÁI ĐẾN PHẢI.

Cập nhật năm 2020:

Tình huống về 3 - 2 - 1có thể có vẻ tầm thường, nếu tuyên bố là, "tất nhiên chúng tôi làm điều đó từ trái sang phải". Nhưng trong các trường hợp khác, chẳng hạn như nếu được thực hiện trong Ruby hoặc trong NodeJS:

$ irb
2.6.3 :001 > 2 ** 3 ** 2
 => 512 

Các **là "với sức mạnh của" nhà điều hành. Sự liên kết là từ phải sang trái. Và nó là

 2 ** (3 ** 2)

đó là 2 ** 9, tức là 512, thay vì

(2 ** 3) ** 2

đó là 8 ** 2, tức là 64.


4
Nếu bạn đã biết câu trả lời, vậy tại sao bạn lại đặt câu hỏi?
Robert Harvey

6
nó là để giúp đỡ những người mới. Tôi nhớ đã học C cách đây rất lâu và mãi sau này mới biết thuyết kết hợp thực sự là gì.
nonopolarity

3
Tôi nghi ngờ rằng hầu hết mọi người học C có thể làm mà không có sự "giúp đỡ" của bạn.

1
hm, chẳng hạn, tính kết hợp bị giới hạn ở cùng một toán tử hay là đối với các toán tử ở cùng mức ưu tiên? Nhiều người có thể trả lời chắc chắn điều đó mà không cần kiểm tra sách hoặc tài liệu tham khảo?
nonopolarity

13
@Neil Butterworth, tại sao lại thù địch như vậy? Tôi nghĩ có thể chấp nhận đăng câu trả lời cho câu hỏi của riêng bạn. Điều này có trong Câu hỏi thường gặp và nó đã được đề cập trong podcast vài lần.
Jay Conrod

3

Tôi cho rằng ý bạn là sự kết hợp toán tử ...

Đó là thứ tự ràng buộc của các toán hạng với một toán tử. Về cơ bản:

a - b + c

có thể được đánh giá là (giả sử - và + có cùng mức độ ưu tiên):

((a - b) + c) hoặc,
(a - (b + c))

Nếu các toán tử được kết hợp bên trái (liên kết ngay lập tức với toán hạng bên trái), nó sẽ được đánh giá là đầu tiên. Nếu chúng là liên kết phù hợp, nó sẽ được đánh giá là thứ hai.


1

Nếu bạn có nghĩa là liên kết toán tử:

Nó xác định cách các biểu thức được phân tích cú pháp. Nó đưa ra một tiêu chuẩn, vì vậy mọi biểu thức đều được phân tích cú pháp giống nhau.

Nó chủ yếu quan trọng đối với các hoạt động có cùng tiền lệ, khi có thể có tác dụng phụ.


0

Hầu hết các ví dụ trước đã sử dụng hằng số. Nếu các đối số là lời gọi hàm, thứ tự các lệnh gọi được thực hiện có thể được xác định bởi các quy tắc kết hợp, tất nhiên tùy thuộc vào trình biên dịch của bạn. Và nếu những chức năng đó có tác dụng phụ ..


0

Tất cả chúng ta đều biết rằng mức độ ưu tiên là quan trọng nhưng tính liên kết trong việc giải thích ý nghĩa của một biểu thức cũng vậy. Để có phần giới thiệu thực sự đơn giản, hãy thử Power of Operator .


0

Sự liên kết xuất hiện theo thứ tự tính toán trong các khái niệm ngôn ngữ lập trình. Thứ tự tính toán xác định ý nghĩa của biểu thức. Nó có hai quy tắc chính,

  1. Quy tắc ưu tiên
  2. Quy tắc liên kết

quy tắc ưu tiên xác định thứ tự mà các toán tử "liền kề" của các kiểu khác nhau được đánh giá. Mọi ngôn ngữ lập trình đều có bảng ưu tiên toán tử riêng liên quan đến các toán tử của nó.

Trở lại với sự liên kết,

Nó xác định thứ tự thực hiện các phép toán liền kề với cùng một mức độ ưu tiên. Nó có 3 hương vị,

thuyết kết hợp
trái - liên kết
phải không liên kết

Nếu một toán tử là liên kết trái, nó đánh giá từ trái sang phải tương tự như vậy nếu nó là liên kết phải, nó sẽ đánh giá từ phải sang trái.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.