¿Qué es la asociatividad de operadores y por qué es importante?


88

¿Qué es la asociatividad (para un operador) y por qué es importante?

Actualizado: asociatividad del operador


2
¿Qué tipo de asociatividad? ¿Asociatividad de operador?
Ikke

26
@Neil Butterworth: ese es un comentario particularmente duro para lo que parece una pregunta razonable. El objetivo del sitio es ser un repositorio central para TODO el conocimiento de programación, incluidas las cosas cubiertas en los textos introductorios. En cuanto a su comentario sobre la respuesta de @Jian Lin a su propio comentario, también es aceptable como se establece en la primera pregunta de las preguntas frecuentes oficiales. Alguien con su nivel de repetición debería saberlo mejor. Si no está de acuerdo con ello, al menos sea civilizado.
Rob Allen

1
@Rob Allen Ver sus otras publicaciones. Además, no dije que no debería responder su propia publicación, solo que no fue útil. Y te haré un trato: no te diré cómo expresar tus publicaciones aquí si no me dices cómo expresar las mías.

Respuestas:


105

Para los operadores, asociatividad significa que cuando el mismo operador aparece en una fila, entonces qué ocurrencia de operador aplicamos primero. En lo siguiente, Qsea ​​el operador

a Q b Q c

Si Qes asociativo a la izquierda, se evalúa como

(a Q b) Q c

Y si es asociativo correcto, se evalúa como

a Q (b Q c)

Es importante, ya que cambia el significado de una expresión. Considere el operador de división con aritmética de enteros, que es asociativo a la izquierda

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

Si fuera asociativo a la derecha, se evaluaría como una expresión indefinida, ya que dividiría por cero

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

¿Sabes cómo encontrar la asociatividad si es izquierda o derecha para una gramática dada?
user2510115

1
Por ejemplo, expr -> expr + term;es asociativo por la izquierda y expr -> term + expres asociativo por la derecha.
Subin Sebastian

15
En la primera línea de su respuesta, en lugar de "cuando aparece el mismo operador", es más apropiado decir "cuando aparecen operadores con la misma precedencia". Ejemplo: a * b / c => donde * y / tienen la misma precedencia.
1O1

2
@ 1O1 gracias, pero ¿qué pasa si esos operadores con la misma precedencia tienen una asociatividad diferente? ¿Cómo a * b / cevaluaría si *sería asociativo por la izquierda pero /sería asociativo por la derecha? Entonces hay una contradicción. Por tanto, creo que hay que decir "cuando los operadores tienen la misma precedencia y asociatividad" si quieres cubrir varios operadores.
Johannes Schaub - litb

2
@ Mark no lo sé, pero no puedo pensar en cómo debería funcionar. Probablemente valga la pena una pregunta adicional sobre el stackoverflow
Johannes Schaub - litb

13

Hay tres tipos de asociatividad:

La propiedad asociativa en matemáticas

Orden de operaciones en lenguajes de programación

Asociatividad en cachés de CPU.

La propiedad asociativa en matemáticas es una propiedad de los operadores como la suma (+). Esta propiedad le permite reorganizar los paréntesis sin cambiar el valor de una declaración, es decir:

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

En los lenguajes de programación, la asociatividad (o fijeza) de un operador es una propiedad que determina cómo se agrupan los operadores de la misma precedencia en ausencia de paréntesis; es decir, en qué orden se evalúa cada operador. Esto puede diferir entre los lenguajes de programación.

En las memorias caché de la CPU, la asociatividad es un método para optimizar el rendimiento.


3
la asociatividad (o fijeza) de un operador es una propiedad que determina cómo se agrupan los operadores de la misma precedencia en ausencia de paréntesis - esa frase fue perfecta para hacerme entender
Rafael Eyng

7

¡¡Sencillo!!

Left Associative means we evaluate our expression from left to right

Right Associative means we evaluate our expression from right to left 

Sabemos que *, / y% tienen la misma precedencia, pero según la asociatividad, la respuesta puede cambiar:

Por ejemplo: tenemos la expresión: 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 haber un error en la respuesta: 2 % 5evalúa 2, no 0.
6005

5

Si se refiere a "asociatividad de operadores", es la forma en que un lenguaje determina cómo se agrupan los operadores de la misma precedencia en ausencia de paréntesis.

Por ejemplo, los operadores + y - en lenguajes basados ​​en C tienen la misma precedencia. Cuando escribe una expresión que usa ambos (sin paréntesis), el compilador debe determinar en qué orden evaluarlos.

Si escribe 12 - 5 + 3, las posibles evaluaciones incluyen:

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

Dependiendo del orden en el que evalúe la expresión, puede obtener diferentes resultados. En los lenguajes basados ​​en C, + y - tienen asociatividad izquierda, lo que significa que la expresión anterior se evaluaría como el primer caso.

Todos los lenguajes tienen reglas fuertemente definidas tanto para la precedencia como para la asociatividad. Puede obtener más información sobre las reglas de C # aquí. Los conceptos generales de asociatividad y precedencia de operadores están bien cubiertos en wikipedia.


Sus ejemplos serían más claros si todos usaran los mismos operandos.
Michael Carman

¿Qué pasaría si dos operadores con la misma precedencia aparecieran en una expresión sin paréntesis, pero uno de ellos tuviera asociatividad izquierda y el otro derecho? ¿Utilizaría simplemente la asociatividad de cualquier operador que encuentre primero?
Héctor

no puede suceder ya que la misma precedencia significa la misma asociatividad. si no fuera así, podrían existir ambigüedades que amenacen la existencia misma de la realidad.
Ankur S

5

es el orden de evaluación de los operadores de la misma precedencia. El orden de IZQUIERDA A DERECHA o DERECHA A IZQUIERDA importa. por

3 - 2 - 1

si es de IZQUIERDA a DERECHA, entonces es

(3 - 2) - 1

y es 0. Si es de DERECHA a IZQUIERDA, entonces es

3 - (2 - 1)

y es 2. En la mayoría de los lenguajes, decimos que el operador menos tiene una asociatividad de IZQUIERDA A DERECHA.

Actualización 2020:

La situación 3 - 2 - 1puede parecer trivial, si la afirmación es, "por supuesto que lo hacemos de izquierda a derecha". Pero en otros casos, como si se hiciera en Ruby o en NodeJS:

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

El **operador está "al poder de". La asociatividad es de derecha a izquierda. Y es

 2 ** (3 ** 2)

que es 2 ** 9, es decir 512, en lugar de

(2 ** 3) ** 2

que es 8 ** 2, es decir, 64.


4
Si ya conocía la respuesta, ¿por qué hizo la pregunta?
Robert Harvey

6
fue para ayudar a gente nueva. Recuerdo haber aprendido C hace mucho tiempo y no supe qué era realmente la asociatividad hasta más tarde.
nopolaridad

3
Sospecho que la mayoría de las personas que aprenden C pueden hacerlo sin su "ayuda".

1
hm, por ejemplo, ¿la asociatividad está limitada al mismo operador, o es para operadores en el mismo nivel de precedencia? ¿Pueden muchas personas responder eso con seguridad sin consultar libros o referencias?
nopolaridad

13
@Neil Butterworth, ¿por qué tan hostil? Creo que es aceptable publicar una respuesta a su propia pregunta. Esto se encuentra en las Preguntas frecuentes y se ha mencionado en el podcast varias veces.
Jay Conrod

3

Supongo que te refieres a la asociatividad del operador ...

Es el orden de vinculación de operandos a un operador. Básicamente:

a - b + c

podría evaluarse como (asumiendo que - y + tienen la misma precedencia):

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

Si los operadores son asociativos a la izquierda (se unen inmediatamente al operando izquierdo), se evaluará como el primero. Si son asociativos a la derecha, se evaluará como el segundo.


1

Si te refieres a la asociatividad del operador:

Define la forma en que se analizan las expresiones. Proporciona un estándar, por lo que cada expresión se analiza de la misma manera.

Es sobre todo importante para las operaciones que tienen el mismo precedente, cuando podría haber efectos secundarios.


0

La mayoría de los ejemplos anteriores han utilizado constantes. Si los argumentos resultan ser llamadas a funciones, el orden en el que se realizan las llamadas puede estar determinado por las reglas de asociación, dependiendo, por supuesto, de su compilador. Y si esas funciones tienen efectos secundarios ...


0

Todos sabemos que la precedencia es importante, pero también lo es la asociatividad al interpretar el significado de una expresión. Para una introducción realmente simple, pruebe Power of Operators .


0

La asociatividad viene bajo el orden de computación en los conceptos del lenguaje de programación. El orden de cálculo determina el significado de la expresión. Tiene dos reglas principales,

  1. Reglas de precedencia
  2. Reglas de asociatividad

Las reglas de precedencia definen el orden en el que se evalúan los operadores "adyacentes" de diferentes tipos. Cada lenguaje de programación tiene su propia tabla de precedencia de operadores con respecto a sus operadores.

Volviendo a la asociatividad,

Define el orden de ejecución de operaciones adyacentes con la misma precedencia. Tiene 3 sabores,

asociatividad izquierda asociatividad
derecha
no asociatividad

Si un operador es asociativo a la izquierda, se evalúa de izquierda a derecha de la misma forma que si es asociativo a la derecha, se evalúa de derecha a izquierda.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.