Czym jest asocjatywność operatorów i dlaczego jest ważna?


88

Co to jest asocjatywność (dla operatora) i dlaczego jest ważna?

Zaktualizowano: asocjatywność operatora


2
Jaki rodzaj asocjatywności? Asocjatywność operatora?
Ikke

26
@Neil Butterworth - To szczególnie ostry komentarz do tego, co wydaje się rozsądnym pytaniem. Cała strona ma być centralnym repozytorium całej wiedzy programistycznej, w tym rzeczy omawianych w tekstach wprowadzających. A jeśli chodzi o komentarz, @Jian Lin odpowiada na swój własny komentarz, który również jest akceptowalny, jak określono w pierwszym pytaniu oficjalnego FAQ. Ktoś z twoim poziomem powtórzeń powinien wiedzieć lepiej. Jeśli się z tym nie zgadzasz, przynajmniej bądź uprzejmy.
Rob Allen

1
@Rob Allen Zobacz inne jego posty. Nie powiedziałem też, że nie powinien odpowiadać na swój własny post, tylko że nie był on pomocny. I zrobię ci układ - nie powiem ci, jak sformułować twoje posty, jeśli nie powiesz mi, jak sformułować moje.

Odpowiedzi:


105

W przypadku operatorów asocjatywność oznacza, że ​​kiedy ten sam operator pojawia się w wierszu, to który operator zastosujemy jako pierwszy. W dalszej części pozwólmy Qbyć operatorem

a Q b Q c

Jeśli Qpozostanie asocjacyjna, zostanie oszacowana jako

(a Q b) Q c

A jeśli jest poprawnie łączny, to ocenia jako

a Q (b Q c)

To ważne, ponieważ zmienia znaczenie wyrażenia. Rozważmy operator dzielenia z arytmetyką liczb całkowitych, która jest asocjacyjna po lewej stronie

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

Gdyby było prawidłowo łączone, zwróciłoby to niezdefiniowane wyrażenie, ponieważ podzieliłbyś przez zero

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

czy wiesz, jak znaleźć asocjatywność, niezależnie od tego, czy jest ona lewa czy prawa dla danej gramatyki?
user2510115

1
Na przykład expr -> expr + term;jest zespolony lewostronnie i expr -> term + exprzespolony prawostronny.
Subin Sebastian

15
W pierwszym wierszu odpowiedzi zamiast „gdy pojawia się ten sam operator” lepiej jest powiedzieć „gdy pojawiają się operatory o takim samym priorytecie”. Przykład: a * b / c => gdzie * i / mają ten sam priorytet.
1O1

2
@ 1O1 dzięki, ale co się stanie, jeśli te operatory z tym samym priorytetem mają różne skojarzenia? Jak a * b / cocenić, czy *byłby lewostronny, ale /prawostronny? Jest też sprzeczność. Myślę więc, że trzeba powiedzieć „gdy operatory o tym samym pierwszeństwie i skojarzeniu”, jeśli chcesz uwzględnić wiele operatorów.
Johannes Schaub - litb

2
@Mark, nie wiem, ale nie mogę myśleć o tym, jak to powinno działać. Prawdopodobnie warte dodatkowego pytania o
przepełnienie stosu

13

Istnieją trzy rodzaje skojarzeń:

Własność asocjacyjna w matematyce

Kolejność operacji w językach programowania

Asocjatywność w pamięci podręcznej procesora.

Właściwość Asocjacja w matematyce jest własnością operatorów, takich jak dodawanie (+). Ta właściwość umożliwia zmianę układu nawiasów bez zmiany wartości instrukcji, tj .:

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

W językach programowania skojarzenie (lub stałość) operatora jest właściwością, która określa, w jaki sposób operatory o tym samym priorytecie są grupowane w przypadku braku nawiasów; tj. w jakiej kolejności oceniany jest każdy operator. Może się to różnić w zależności od języka programowania.

W pamięci podręcznej procesora asocjatywność jest metodą optymalizacji wydajności.


3
asocjatywność (lub stałość) operatora jest właściwością, która określa, w jaki sposób operatory o tym samym priorytecie są grupowane bez nawiasów - to wyrażenie było po prostu idealne, aby mnie zrozumieć
Rafael Eyng

7

Prosty!!

Left Associative means we evaluate our expression from left to right

Right Associative means we evaluate our expression from right to left 

Wiemy, że *, / i% mają ten sam priorytet, ale zgodnie z asocjatywnością odpowiedź może się zmienić:

Na przykład: Mamy wyrażenie: 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
Wydaje się, że w odpowiedzi jest błąd: 2 % 5ocenia do 2, a nie 0.
6005

5

Jeśli odnosisz się do „asocjatywności operatorów” - jest to sposób, w jaki język określa sposób grupowania operatorów o tym samym priorytecie bez nawiasów.

Na przykład operatory + i - w językach opartych na języku C mają ten sam priorytet. Kiedy piszesz wyrażenie, które używa obu z nich (bez nawiasów), kompilator musi określić, w jakiej kolejności mają je oceniać.

Jeśli napiszesz 12 - 5 + 3, możliwe oceny obejmują:

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

W zależności od kolejności, w jakiej obliczasz wyrażenie, możesz uzyskać różne wyniki. W językach opartych na C znaki + i - pozostawiły asocjatywność, co oznacza, że ​​powyższe wyrażenie zostanie ocenione jako pierwszy przypadek.

Wszystkie języki mają ściśle zdefiniowane reguły zarówno dotyczące pierwszeństwa, jak i asocjatywności. Możesz dowiedzieć się więcej o regułach języka C # tutaj. Ogólne koncepcje asocjatywności i pierwszeństwa operatorów są dobrze omówione na Wikipedii.


Twoje przykłady byłyby jaśniejsze, gdyby wszystkie używały tych samych operandów.
Michael Carman

Co by się stało, gdyby dwa operatory o tym samym priorytecie pojawiły się w wyrażeniu bez parantez, ale jeden z nich pozostawił łączność, a drugi miał rację? Czy użyłby po prostu skojarzenia, którego kiedykolwiek znajdzie operator?
Hector

nie może się zdarzyć, ponieważ ten sam priorytet oznacza tę samą łączność. gdyby tak nie było, mogłyby istnieć niejasności zagrażające samemu istnieniu rzeczywistości.
Ankur S

5

jest to kolejność oceny operatorów o tym samym priorytecie. Zlecenie od lewej do prawej lub od prawej do lewej ma znaczenie. Dla

3 - 2 - 1

jeśli jest od lewej do prawej, to tak

(3 - 2) - 1

i wynosi 0. Jeśli jest od prawej do lewej, to jest

3 - (2 - 1)

i wynosi 2. W większości języków mówimy, że operator minus ma asocjatywność od lewej do prawej.

Aktualizacja 2020:

Sytuacja 3 - 2 - 1może wydawać się trywialna, jeśli twierdzi się, że „oczywiście robimy to od lewej do prawej”. Ale w innych przypadkach, na przykład w Rubim lub NodeJS:

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

Operator **jest „do potęgi”. Asocjatywność jest od prawej do lewej. I to jest

 2 ** (3 ** 2)

co jest 2 ** 9, to znaczy 512, zamiast

(2 ** 3) ** 2

co jest 8 ** 2, tj 64.


4
Jeśli znałeś już odpowiedź, to dlaczego zadałeś to pytanie?
Robert Harvey

6
miała pomóc nowym ludziom. Pamiętam, że nauczyłem się C dawno temu i dopiero później nie wiedziałem, czym tak naprawdę jest asocjatywność.
polaryzacji

3
Podejrzewam, że większość osób uczących się C poradzi sobie bez Twojej „pomocy”.

1
hm, na przykład, czy asocjatywność jest ograniczona do tego samego operatora, czy też do operatorów na tym samym poziomie pierwszeństwa? Czy wiele osób może odpowiedzieć na to pytanie bez sprawdzania książek lub referencji?
niepolarność

13
@Neil Butterworth, dlaczego tak wrogi? Myślę, że opublikowanie odpowiedzi na własne pytanie jest dopuszczalne. To jest w FAQ i było wspominane w podcastach kilka razy.
Jay Conrod

3

Zakładam, że masz na myśli asocjatywność operatorów ...

To kolejność wiązania operandów z operatorem. Gruntownie:

a - b + c

można ocenić jako (przy założeniu, że - i + mają ten sam priorytet):

((a - b) + c) lub
(a - (b + c))

Jeśli operatory są pozostawione asocjacyjnie (łączą się natychmiast z lewym operandem), zostaną ocenione jako pierwsze. Jeśli są prawidłowo asocjatywne, zostaną ocenione jako drugie.


1

Jeśli masz na myśli asocjatywność operatorów:

Definiuje sposób analizowania wyrażeń. Daje standard, więc każde wyrażenie jest analizowane w ten sam sposób.

Jest to szczególnie ważne w przypadku operacji, które mają ten sam precedens, kiedy mogą wystąpić skutki uboczne.


0

Większość poprzednich przykładów wykorzystywała stałe. Jeśli argumenty są wywołaniami funkcji, kolejność wywołań może być określona przez reguły asocjacyjne, w zależności oczywiście od kompilatora. A jeśli te funkcje mają skutki uboczne ...


0

Wszyscy wiemy, że pierwszeństwo jest ważne, ale tak samo jak łączność w interpretacji znaczenia wyrażenia. Aby uzyskać naprawdę proste wprowadzenie, wypróbuj Power of Operators .


0

Asocjatywność podlega kolejności obliczeń w pojęciach języka programowania. Kolejność obliczeń określa znaczenie wyrażenia. Ma dwie główne zasady,

  1. Zasady pierwszeństwa
  2. Reguły kojarzenia

reguły pierwszeństwa definiują kolejność, w jakiej są oceniane „sąsiednie” operatory różnych typów. Każdy język programowania ma swoją własną tabelę pierwszeństwa operatorów dotyczącą jego operatorów.

Wracając do skojarzeń,

Definiuje kolejność wykonywania sąsiednich operacji z tym samym priorytetem. Posiada 3 smaki,

asocjatywność lewostronna asocjatywność
prawostronna
asocjatywność

Jeśli operator jest skojarzony lewostronnie, oblicza od lewej do prawej, podobnie, jeśli jest skojarzony z prawej strony, oblicza od prawej do lewej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.