O que é associatividade de operadores e por que é importante?


88

O que é associatividade (para um operador) e por que é importante?

Atualizado: associatividade do operador


2
Que tipo de associatividade? Associatividade do operador?
Ikke

26
@Neil Butterworth - Esse é um comentário particularmente severo para o que parece uma pergunta razoável. O objetivo do site é ser um repositório central para TODO o conhecimento de programação, incluindo coisas abordadas em textos introdutórios. Quanto ao seu comentário sobre a resposta de @Jian Lin ao seu próprio comentário, isso também é aceitável, conforme exposto na primeira pergunta do FAQ oficial. Alguém com seu nível de repetição deve saber melhor. Se você discordar, pelo menos seja civilizado.
Rob Allen

1
@Rob Allen Veja seus outros posts. Além disso, eu não disse que ele não deveria responder a sua própria postagem, apenas que não foi útil. E farei um acordo com você - não direi como formular suas postagens aqui, se você não me disser como formular as minhas.

Respostas:


105

Para operadores, associatividade significa que, quando o mesmo operador aparece em uma linha, então qual ocorrência de operador aplicamos primeiro. A seguir, deixe Qser o operador

a Q b Q c

Se Qfor associativo à esquerda, ele será avaliado como

(a Q b) Q c

E se for associativa correta, então avalia como

a Q (b Q c)

É importante, pois muda o significado de uma expressão. Considere o operador de divisão com aritmética inteira, que é associativa à esquerda

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

Se fosse associativo correto, seria avaliado como uma expressão indefinida, já que você dividiria por zero

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

você sabe como encontrar associatividade se é esquerda ou direita para determinado grammer?
user2510115

1
Por exemplo, expr -> expr + term;é associativo à esquerda e expr -> term + exprassociativo à direita.
Subin Sebastian,

15
Na primeira linha de sua resposta, em vez de "quando o mesmo operador aparece", é mais apropriado dizer "quando aparecem operadores de mesma precedência". Exemplo: a * b / c => onde * e / têm a mesma precedência.
1O1 de

2
@ 1O1 obrigado, mas o que acontece se esses operadores com a mesma precedência tiverem associatividade diferente? Como avaliaria a * b / cse *seria associativo à esquerda, mas /seria associativo à direita? Então há uma contradição. Portanto, acho que é necessário dizer "quando os operadores com a mesma precedência e associatividade" se quiser abranger vários operadores.
Johannes Schaub - litb

2
@Marque não sei, mas não consigo pensar em como deveria funcionar. Provavelmente vale uma pergunta sobre stackoverflow extra
Johannes Schaub - litb

13

Existem três tipos de associatividade:

A propriedade associativa em matemática

Ordem de operações em linguagens de programação

Associatividade em caches de CPU.

A propriedade associativa em matemática é uma propriedade de operadores como adição (+). Esta propriedade permite reorganizar os parênteses sem alterar o valor de uma instrução, ou seja:

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

Em linguagens de programação, a associatividade (ou fixidez) de um operador é uma propriedade que determina como os operadores de mesma precedência são agrupados na ausência de parênteses; ou seja, em que ordem cada operador é avaliado. Isso pode ser diferente entre as linguagens de programação.

Em caches de CPU, a associatividade é um método de otimização de desempenho.


3
a associatividade (ou fixidez) de um operador é uma propriedade que determina como os operadores da mesma precedência são agrupados na ausência de parênteses - essa frase foi perfeita para me fazer entender
Rafael Eyng

7

Simples!!

Left Associative means we evaluate our expression from left to right

Right Associative means we evaluate our expression from right to left 

Sabemos que *, / e% têm a mesma precedência, mas de acordo com a associatividade, a resposta pode mudar:

Por exemplo: Temos a expressão: 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
Parece haver um erro na resposta: 2 % 5avalia para 2, não 0.
6005

5

Se você está se referindo a "associatividade do operador" - é como uma linguagem determina como os operadores da mesma precedência são agrupados na ausência de parênteses.

Por exemplo, os operadores + e - em linguagens baseadas em C têm a mesma precedência. Quando você escreve uma expressão que usa os dois (sem parênteses), o compilador deve determinar em qual ordem avaliá-los.

Se você escrever 12 - 5 + 3, as avaliações possíveis incluem:

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

Dependendo da ordem em que você avalia a expressão, você pode obter resultados diferentes. Em linguagens baseadas em C, + e - têm associatividade à esquerda, o que significa que a expressão acima seria avaliada como o primeiro caso.

Todas as linguagens têm regras fortemente definidas para precedência e associatividade. Você pode aprender mais sobre as regras para C # aqui. Os conceitos gerais de associatividade e precedência do operador são bem abordados na Wikipedia.


Seus exemplos seriam mais claros se todos usassem os mesmos operandos.
Michael Carman

O que aconteceria se dois operadores com a mesma precedência aparecessem em uma expressão sem parênteses, mas um deles tivesse associatividade à esquerda e o outro à direita? Ele apenas usaria a associatividade de qualquer operador que encontrasse primeiro?
Hector

isso não pode acontecer, pois a mesma precedência significa a mesma associatividade. se não fosse esse o caso, poderiam haver ambigüidades que ameaçam a própria existência da realidade.
Ankur S

5

é a ordem de avaliação para operadores de mesma precedência. A ordem da ESQUERDA PARA A DIREITA ou DA DIREITA PARA A ESQUERDA é importante. Para

3 - 2 - 1

se for da ESQUERDA para a DIREITA, então é

(3 - 2) - 1

e é 0. Se for DIREITO para ESQUERDO, então é

3 - (2 - 1)

e é 2. Na maioria das linguagens, dizemos que o operador menos tem uma associatividade da ESQUERDA PARA A DIREITA.

Atualização 2020:

A situação sobre 3 - 2 - 1pode parecer trivial, se a afirmação for, "é claro que fazemos da esquerda para a direita". Mas em outros casos, como se feito em Ruby ou em NodeJS:

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

O **operador está "ao poder de". A associatividade é da direita para a esquerda. E isso é

 2 ** (3 ** 2)

que é 2 ** 9, ou seja 512, em vez de

(2 ** 3) ** 2

que é 8 ** 2, ou seja 64,.


4
Se você já sabia a resposta, por que fez a pergunta?
Robert Harvey

6
era para ajudar novas pessoas. Lembro-me de ter aprendido C há muito tempo e não sabia o que realmente era associatividade até mais tarde.
polaridade

3
Suspeito que a maioria das pessoas que estão aprendendo C pode passar sem a sua "ajuda".

1
hm, por exemplo, a associatividade é limitada ao mesmo operador ou é para operadores no mesmo nível de precedência? Muitas pessoas podem responder isso com certeza, sem verificar livros ou referências?
polaridade

13
@Neil Butterworth, por que tão hostil? Eu acho que é aceitável postar uma resposta para sua própria pergunta. Isso está no FAQ e foi mencionado no podcast várias vezes.
Jay Conrod

3

Suponho que você quer dizer associatividade do operador ...

É a ordem de vinculação de operandos a um operador. Basicamente:

a - b + c

pode ser avaliado como (assumindo que - e + tenham a mesma precedência):

((a - b) + c) ou,
(a - (b + c))

Se os operadores forem associativos à esquerda (vinculam imediatamente ao operando à esquerda), ele será avaliado como o primeiro. Se eles forem associativos corretos, será avaliado como o segundo.


1

Se você quer dizer associatividade do operador:

Ele define a maneira como as expressões são analisadas. Ele fornece um padrão, de modo que cada expressão é analisada da mesma maneira.

É mais importante para operações que têm o mesmo precedente, quando pode haver efeitos colaterais.


0

A maioria dos exemplos anteriores usou constantes. Se os argumentos forem chamadas de função, a ordem em que as chamadas são feitas pode ser determinada pelas regras de associação, dependendo, é claro, do seu compilador. E se essas funções tiverem efeitos colaterais ..


0

Todos nós sabemos que a precedência é importante, mas também a associatividade na interpretação do significado de uma expressão. Para uma introdução realmente simples, experimente Power of Operators .


0

A associatividade está sob a ordem de computação nos conceitos de linguagem de programação. A ordem de cálculo determina o significado da expressão. Tem duas regras principais,

  1. Regras de precedência
  2. Regras de associatividade

as regras de precedência definem a ordem na qual os operadores "adjacentes" de diferentes tipos são avaliados. Cada linguagem de programação tem sua própria tabela de precedência de operadores em relação a seus operadores.

Voltando à associatividade,

Ele define a ordem de execução das operações adjacentes com a mesma precedência. Tem 3 sabores,

deixou-associatividade
direito do associatividade
não associatividade

Se um operador for associativo à esquerda, ele avalia da esquerda para a direita da mesma forma, se for associativo à direita, ele avalia da direita para a esquerda.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.