Що таке асоціативність операторів і чому це важливо?


88

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

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


2
Що за асоціативність? Асоціативність оператора?
Ікке,

26
@ Ніл Баттерворт - Це особливо різкий коментар щодо, здається, розумного запитання. Вся суть сайту має бути центральним сховищем ВСІХ знань з програмування, включаючи речі, висвітлені у вступних текстах. Що стосується Вашого коментаря щодо відповіді @Jian Lin на його власний коментар, це також є прийнятним, як це викладено в першому питанні офіційних поширених запитань. Хтось із вашим рівнем представників повинен знати краще. Якщо ви з цим не погоджуєтесь, принаймні будьте цивільні щодо цього.
Роб Аллен,

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

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

Якщо ви маєте на увазі "асоціативність операторів" - це те, як мова визначає, як оператори того самого пріоритету групуються за відсутності дужок.

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

Якщо ви пишете 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
@ Ніл Баттерворт, чому такий ворожий? Я вважаю прийнятним розміщення відповіді на власне запитання. Це є у поширених запитаннях, і про це вже кілька разів згадувалось у подкасті.
Джей Конрод,

3

Припускаю, ви маєте на увазі асоціативність оператора ...

Це порядок прив’язки операндів до оператора. В основному:

a - b + c

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

((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.