En los lenguajes de programación , la asociatividad de un operador es una propiedad que determina cómo se agrupan los operadores de la misma precedencia en ausencia de paréntesis . Si un operando está precedido y seguido por operadores (por ejemplo, ^ 3 ^
), y esos operadores tienen la misma precedencia, entonces el operando puede usarse como entrada para dos operaciones diferentes (es decir, las dos operaciones indicadas por los dos operadores). La elección de las operaciones a las que se aplicará el operando está determinada por la asociatividad de los operadores. Los operadores pueden ser asociativos (lo que significa que las operaciones se pueden agrupar arbitrariamente),asociativo a la izquierda (es decir, las operaciones se agrupan desde la izquierda), asociativo a la derecha (es decir, las operaciones se agrupan desde la derecha) o no asociativo (es decir, las operaciones no se pueden encadenar, a menudo porque el tipo de salida es incompatible con los tipos de entrada) . La asociatividad y la precedencia de un operador es parte de la definición del lenguaje de programación; diferentes lenguajes de programación pueden tener diferente asociatividad y precedencia para el mismo tipo de operador.
Considere la expresión a ~ b ~ c
. Si el operador ~
tiene asociatividad a la izquierda, esta expresión se interpretaría como (a ~ b) ~ c
. Si el operador tiene asociatividad derecha, la expresión se interpretaría como a ~ (b ~ c)
. Si el operador no es asociativo, la expresión puede ser un error de sintaxis o puede tener algún significado especial. Algunos operadores matemáticos tienen asociatividad inherente. Por ejemplo, la resta y la división, como se usan en la notación matemática convencional, son inherentemente asociativas a la izquierda. La suma y la multiplicación, por el contrario, son asociativas tanto de izquierda como de derecha. (por ejemplo (a * b) * c = a * (b * c)
).
Muchos manuales de lenguajes de programación proporcionan una tabla de precedencia y asociatividad de los operadores; consulte, por ejemplo, la tabla para C y C ++ .
El concepto de asociatividad notacional descrito aquí está relacionado con la asociatividad matemática, pero es diferente . Una operación que es matemáticamente asociativa, por definición, no requiere asociatividad de notación. (Por ejemplo, la suma tiene la propiedad asociativa, por lo tanto, no tiene que ser asociativa por la izquierda ni por la derecha). Sin embargo, una operación que no es asociativa matemáticamente debe ser en notación izquierda, derecha o no asociativa. (Por ejemplo, la resta no tiene la propiedad asociativa, por lo tanto, debe tener asociatividad en notación).
Ejemplos de
La asociatividad solo es necesaria cuando los operadores de una expresión tienen la misma precedencia. Por lo general +
y -
tienen la misma precedencia. Considere la expresión 7 - 4 + 2
. El resultado podría ser (7 - 4) + 2 = 5
o 7 - (4 + 2) = 1
. El primer resultado corresponde al caso en el que +
y -
son asociativos a la izquierda, el segundo a cuando +
y -
son asociativos a la derecha.
Para reflejar el uso normal, los operadores de suma , resta , multiplicación y división suelen ser asociativos por la izquierda, [1] [2] [3] [4] [5] mientras que para un operador de exponenciación (si está presente) [6] y Operadores de flecha hacia arriba de Knuth no hay un acuerdo general. Los operadores de asignación suelen ser asociativos por la derecha. Para evitar casos en los que los operandos estén asociados con dos operadores, o sin ningún operador, los operadores con la misma precedencia deben tener la misma asociatividad.
Un ejemplo detallado
Considere la expresión 5^4^3^2
, en la que ^
se toma como un operador de exponenciación asociativa a la derecha. Un analizador que lea los tokens de izquierda a derecha aplicaría la regla de asociatividad a una rama, debido a la asociatividad a la derecha de ^
, de la siguiente manera:
- Plazo
5
se lee. ^
Se lee el no terminal . Nodo: "5^
".- Plazo
4
se lee. Nodo: "5^4
". ^
Se lee el no terminal , lo que activa la regla de asociatividad a la derecha. La asociatividad decide el nodo: "5^(4^
".- Plazo
3
se lee. Nodo: "5^(4^3
". ^
Se lee el no terminal , lo que desencadena la reaplicación de la regla de asociatividad por la derecha. Nodo "5^(4^(3^
".- Plazo
2
se lee. Nodo "5^(4^(3^2
". - No hay tokens para leer. Aplicar asociatividad para producir un árbol de análisis sintáctico "
5^(4^(3^2))
".
Esto luego se puede evaluar en profundidad primero, comenzando en el nodo superior (el primero ^
):
- El evaluador baja por el árbol, desde la primera, pasando por la segunda, hasta la tercera
^
expresión. - Se evalúa como: 3 2 = 9. El resultado reemplaza la rama de expresión como el segundo operando del segundo
^
. - La evaluación continúa un nivel hacia arriba en el árbol de análisis como: 4 9 = 262144. Nuevamente, el resultado reemplaza la rama de expresión como el segundo operando del primero
^
. - Nuevamente, el evaluador aumenta el árbol hasta la expresión raíz y evalúa como: 5 262144 ≈ 6,2060699 × 10 183230 . La última rama restante se colapsa y el resultado se convierte en el resultado general, por lo que se completa la evaluación general.
Una evaluación asociativa a la izquierda habría dado como resultado el árbol de análisis sintáctico ((5^4)^3)^2
y los resultados completamente diferentes 625, 244140625 y finalmente ~ 5.9604645 × 10 16 .
Asociatividad derecha de los operadores de asignación
En muchos lenguajes de programación imperativos , el operador de asignación se define como asociativo por la derecha y la asignación se define como una expresión (que se evalúa como un valor), no solo una declaración. Esto permite la asignación encadenada utilizando el valor de una expresión de asignación como el operando derecho de la siguiente expresión de asignación.
En C , la asignación a = b
es una expresión que se evalúa con el mismo valor que la expresión b
convertida al tipo de a
, con el efecto secundario de almacenar el valor R de b
en el valor L de a
. [a] Por tanto, la expresión a = (b = c)
se puede interpretar como b = c; a = c;
. La expresión alternativa (a = b) = c
genera un error porque a = b
no es una expresión de valor L, es decir, tiene un valor R pero no un valor L donde almacenar el valor R de c
. La asociatividad a la derecha del =
operador permite que expresiones a = b = c
como a = (b = c)
.
En C ++ , la asignación a = b
es una expresión que se evalúa con el mismo valor que la expresión a
, con el efecto secundario de almacenar el valor R de b
en el valor L de a
. Por lo tanto, la expresión a = (b = c)
aún se puede interpretar como b = c; a = c;
. Y la expresión alternativa (a = b) = c
se puede interpretar como en a = b; a = c;
lugar de generar un error. La asociatividad a la derecha del =
operador permite que expresiones a = b = c
como a = (b = c)
.
Operadores no asociativos
Los operadores no asociativos son operadores que no tienen un comportamiento definido cuando se usan en secuencia en una expresión. En Prolog, el operador infijo no:-
es asociativo porque construcciones como " a :- b :- c
" constituyen errores de sintaxis.
Otra posibilidad es que las secuencias de ciertos operadores se interpreten de alguna otra forma, lo que no puede expresarse como asociatividad. Esto generalmente significa que sintácticamente, hay una regla especial para las secuencias de estas operaciones, y semánticamente el comportamiento es diferente. Un buen ejemplo es Python , que tiene varias de estas construcciones. [7] Dado que las asignaciones son declaraciones, no operaciones, el operador de asignación no tiene un valor y no es asociativo. En cambio, la asignación encadenada se implementa al tener una regla gramatical para secuencias de asignaciones a = b = c
, que luego se asignan de izquierda a derecha. Además, combinaciones de asignación y la asignación aumentada, como a = b += c
no son legales en Python, aunque son C. legal Otro ejemplo son los operadores de comparación, tales como >
, ==
, y <=
. Una comparación encadenada como a < b < c
se interpreta como (a < b) and (b < c)
, no equivalente a (a < b) < c
o a < (b < c)
. [8]
Ver también
- Orden de operaciones (en aritmética y álgebra)
- Notación de operador común (en lenguajes de programación)
- Asociatividad (la propiedad matemática de la asociatividad)
Notas
- ^ Una expresión se puede convertir en una declaración siguiéndola con un punto y coma;
a = b
esdecir,es una expresión peroa = b;
es una declaración.
Referencias
- ^ Bronstein, Ilja Nikolaevič; Semendjajew, Konstantin Adolfovič (1987) [1945]. "2.4.1.1.". En Grosche, Günter; Ziegler, Viktor; Ziegler, Dorothea (eds.). Taschenbuch der Mathematik (en alemán). 1 . Traducido por Ziegler, Viktor. Weiß, Jürgen (23 ed.). Thun y Frankfurt am Main: Verlag Harri Deutsch (y BG Teubner Verlagsgesellschaft , Leipzig). págs. 115-120. ISBN 3-87144-492-8.
- ^ Universidad Tecnológica de Chemnitz : Prioridad y asociatividad de los operadores ( traducción archivada )
- ^ Lugar de educación: el orden de las operaciones
- ↑ Khan Academy : The Order of Operations , marca de tiempo 5m40s
- ^ Departamento de Educación de Virginia: Uso del orden de operaciones y exploración de propiedades , sección 9
- ^ Asociatividad de exponenciación y código de notación matemática estándar . 23 de agosto de 2016. Consultado el 20 de septiembre de 2016.
- ^ La referencia del lenguaje Python , " 6. Expresiones "
- ^ La referencia del lenguaje Python , " 6. Expresiones ": 6.9. Comparaciones