Что такое ассоциативность операторов и почему это важно?


88

Что такое ассоциативность (для оператора) и почему она важна?

Обновлено: ассоциативность операторов


2
Что за ассоциативность? Ассоциативность операторов?
Икке

26
@Neil Butterworth - Это особенно резкий комментарий по поводу разумного вопроса. Весь смысл сайта в том, чтобы быть центральным хранилищем ВСЕХ знаний по программированию, включая то, что описано во вводных текстах. Что касается вашего комментария к ответу @Jian Lin на его собственный комментарий, который тоже приемлем, как указано в первом вопросе официального FAQ. Кто-то с вашим уровнем репутации должен знать лучше. Если вы не согласны с этим, по крайней мере, будьте вежливы.
Роб Аллен

1
@Rob Allen См. Другие его сообщения. Кроме того, я не сказал, что он не должен отвечать на свой собственный пост, только то, что он бесполезен. И я сделаю вам сделку - я не скажу вам, как сформулировать здесь свои сообщения, если вы не скажете мне, как сформулировать мои.

Ответы:


105

Для операторов ассоциативность означает, что когда один и тот же оператор появляется в строке, то какой оператор мы применяем в первую очередь. В дальнейшем пусть Q- оператор

a Q b Q c

Если Qлевоассоциативный, то он оценивается как

(a Q b) Q c

И если он правильно ассоциативен, то оценивается как

a Q (b Q c)

Это важно, так как меняет смысл выражения. Рассмотрим оператор деления с целочисленной арифметикой, который является левоассоциативным.

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

Если бы он был правильно ассоциативным, он оценил бы неопределенное выражение, так как вы бы делили на ноль

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

Вы знаете, как найти ассоциативность, левая она или правая для данного грамматика?
user2510115 04

1
Например, expr -> expr + term;он ассоциативен слева и ассоциативен expr -> term + exprсправа.
Субин Себастьян

15
В первой строке вашего ответа вместо «когда появляется тот же оператор» более уместно сказать «когда появляются операторы с одинаковым приоритетом». Пример: a * b / c => где * и / имеют одинаковый приоритет.
1O1

2
@ 1O1 спасибо, но что произойдет, если операторы с одинаковым приоритетом будут иметь разную ассоциативность? Как бы a * b / cоценить, *будет ли оно левоассоциативным, но /правоассоциативным? Тогда есть противоречие. Поэтому я думаю, что нужно сказать «когда операторы с одинаковым приоритетом и ассоциативностью», если вы хотите охватить несколько операторов.
Йоханнес Шауб - лит

2
@Mark, я не знаю, но я не могу думать, как это должно работать. Вероятно, стоит задать дополнительный вопрос о
переполнении стека

13

Есть три вида ассоциативности:

Ассоциативное свойство в математике

Порядок операций в языках программирования

Ассоциативность в кэше ЦП.

Свойство ассоциативности в математике - это свойство таких операторов, как сложение (+). Это свойство позволяет вам переставлять круглые скобки, не меняя значения оператора, то есть:

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

В языках программирования ассоциативность (или фиксированность) оператора - это свойство, которое определяет, как операторы с одинаковым приоритетом группируются при отсутствии круглых скобок; т.е. в каком порядке оценивается каждый оператор. Это может отличаться в зависимости от языка программирования.

В кэшах ЦП ассоциативность - это метод оптимизации производительности.


3
ассоциативность (или фиксированность) оператора - это свойство, определяющее, как операторы с одинаковым приоритетом группируются без скобок - эта фраза была просто идеальной, чтобы я понял
Рафаэль Эйнг

7

Просто!!

Left Associative means we evaluate our expression from left to right

Right Associative means we evaluate our expression from right to left 

Мы знаем, что *, / и% имеют одинаковый приоритет, но в соответствии с ассоциативностью ответ может измениться:

Например: у нас есть выражение: 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
Кажется, в ответе есть ошибка: 2 % 5оценивает 2, а не 0.
6005,

5

Если вы имеете в виду «ассоциативность операторов» - это то, как язык определяет, как операторы с одинаковым приоритетом группируются без скобок.

Например, операторы + и - в языках на основе C имеют одинаковый приоритет. Когда вы пишете выражение, которое использует оба из них (без скобок), компилятор должен определить, в каком порядке их оценивать.

Если вы напишете 12 - 5 + 3, возможные оценки включают:

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

В зависимости от порядка, в котором вы оцениваете выражение, вы можете получить разные результаты. В языках на основе C + и - оставили ассоциативность, что означает, что выражение выше будет оцениваться как первый регистр.

У всех языков есть строго определенные правила как для приоритета, так и для ассоциативности. Вы можете узнать больше о правилах для C # здесь. Общие концепции ассоциативности и приоритета операторов подробно описаны в Википедии.


Ваши примеры были бы более ясными, если бы все они использовали одни и те же операнды.
Майкл Карман

Что произойдет, если в выражении без скобок появятся два оператора с одинаковым приоритетом, но один из них имеет левую ассоциативность, а другой - правую? Будет ли он просто использовать ассоциативность того оператора, который найдет первым?
Гектор

это не может произойти, поскольку одна и та же последовательность означает ту же ассоциативность. если бы это было не так, могла бы быть двусмысленность, которая угрожает самому существованию реальности.
Ankur S

5

это порядок оценки для операторов с одинаковым приоритетом. Порядок «ВЛЕВО НАПРАВО» или «ВПРАВО НАЛЕВО» имеет значение. За

3 - 2 - 1

если он СЛЕВА НАПРАВО, то это

(3 - 2) - 1

и равно 0. Если это ВПРАВО НАЛЕВО, то это

3 - (2 - 1)

и это 2. В большинстве языков мы говорим, что оператор минус имеет ассоциативность ВЛЕВО НАПРАВО.

Обновление 2020:

Ситуация 3 - 2 - 1может показаться тривиальной, если заявить: «Конечно, мы делаем это слева направо». Но в других случаях, например, в Ruby или NodeJS:

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

Оператор **«во власти». Ассоциативность - справа налево. И это

 2 ** (3 ** 2)

что есть 2 ** 9, т. е. 512вместо

(2 ** 3) ** 2

что 8 ** 2, то есть 64.


4
Если вы уже знали ответ, то почему вы задали вопрос?
Роберт Харви

6
это было помочь новым людям. Я помню, как изучал Си давным-давно и не знал, что такое ассоциативность на самом деле, до позднего времени.
неполярность

3
Я подозреваю, что большинство людей, изучающих C, могут обойтись без вашей «помощи».

1
hm, например, ограничивается ли ассоциативность одним и тем же оператором или для операторов с одним и тем же уровнем приоритета? Многие ли люди могут ответить на этот вопрос с уверенностью, не заглядывая в книги или ссылки?
неполярность

13
@ Нил Баттерворт, почему так враждебно? Я считаю приемлемым разместить ответ на свой вопрос. Это есть в FAQ и несколько раз упоминалось в подкасте.
Джей Конрод,

3

Я предполагаю, что вы имеете в виду ассоциативность операторов ...

Это порядок привязки операндов к оператору. В принципе:

а - б + в

может быть оценено как (при условии, что - и + имеют одинаковый приоритет):

((a - b) + c) или,
(a - (b + c))

Если операторы оставлены ассоциативными (сразу же связываются с левым операндом), он будет оценен как первый. Если они правильно ассоциативны, это будет оценено как второе.


1

Если вы имеете в виду ассоциативность операторов:

Он определяет способ анализа выражений. Он дает стандарт, поэтому все выражения анализируются одинаково.

Это в основном важно для операций с одинаковым прецедентом, когда могут возникнуть побочные эффекты.


0

В большинстве предыдущих примеров использовались константы. Если аргументы являются вызовами функций, порядок, в котором выполняются вызовы, может определяться правилами ассоциации, в зависимости, конечно, от вашего компилятора. И если у этих функций есть побочные эффекты ...


0

Все мы знаем, что приоритет важен, но не менее важна ассоциативность при интерпретации значения выражения. Для действительно простого вступления попробуйте Power of Operators .


0

В концепциях языка программирования ассоциативность определяется порядком вычислений. Порядок вычисления определяет смысл выражения. В нем есть два основных правила:

  1. Правила приоритета
  2. Правила ассоциативности

Правила приоритета определяют порядок, в котором оцениваются «смежные» операторы разных типов. Каждый язык программирования имеет свою собственную таблицу приоритета операторов в отношении своих операторов.

Возвращаясь к ассоциативности,

Он определяет порядок выполнения смежных операций с одинаковым приоритетом. Имеет 3 вкуса,

левоассоциативность
правоассоциативность
неассоциативность

Если оператор левоассоциативен, он оценивается слева направо, а если он ассоциативен справа, он оценивается справа налево.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.