Operadores de asignación¶
El operador =
es un operador sobrecargado. Un operador se llama
sobrecargado cuando dependiendo del contexto acomete
distintas operaciones. En el contexto de la asignación, el operador =
se utiliza para modificar el valor de las variables, es decir,
altera el bloque de memoria asociado a una variable.
Analizando la tabla de precedencia completa observa que es uno los operadores con menor precedencia. Por tanto, en una sentencia simple típica, será la última operación realizada.
Supongamos que y
es una variable de tipo double
ligada a un bloque de memoria con
valor 2.0
.
![../../_images/asignacion_antes.png](../../_images/asignacion_antes.png)
y = y + 1.5;
Tras obtener el resultado de la expresión y + 1.5
, inmediatamente después de
la asignación y
tendrá un valor 3.5
.
![../../_images/asignacion_despues.png](../../_images/asignacion_despues.png)
Advertencia
El operador de asignación no es equivalente a la igualdad matemática:
una sentencia como la anterior, y = y + 1.5;
, no tiene sentido en matemáticas.
Valores por la izquierda y valores por la derecha¶
Una expresión genera un valor por la izquierda (Lvalue) cuando el bloque de memoria donde se almacena el resultado obtenido es accesible desde el programa y, por tanto, persiste y podemos modificarlo posteriormente.
El nombre se debe a que estas expresiones normalmente se utilizan en el lado izquierdo del
operador de asignación =
. Típicamente son nombres de variables.
Por el contrario, una expresión genera un valor por la derecha (Rvalue) cuando el bloque de memoria donde será almacenado no tiene una posición específica: probablemente se almacenará temporalmente en algún registro de la CPU durante la ejecución del programa.
Una expresión Rvalue no puede aparecer nunca en el lado izquierdo del
operador de asignación =
.
y = 5;
x = (y + 3) + 8;
z = x + 3;
En la segunda sentencia del anterior fragmento de código, x
es una expresión Lvalue,
pero (y + 3)
es una expresión Rvalue. En algún momento de la ejecución de la sentencia
el resultado de (y + 3)
, que es 8
, se almacenará en algún registro de la CPU.
Pero en ningún momento podemos acceder a esa posición de memoria: el resultado 8
no persiste.
Por el contrario, el valor de x
tras la ejecución de la sentencia, 16
, persiste,
es accesible. Por ello, podemos reusarlo en la siguiente línea.
Por ello, en general, a la izquierda de la asignación siempre aparece una variable. A la derecha cualquier expresión válida.
y = (2 + 3.5)/3.1 + a; // OK
vel = x; // OK
masa = 5.6; // OK
x + y = u + w; // ERROR
2 = z; // ERROR
El operador de asignación es de los pocos operadores que se evalúan de derecha a izquierda.
Por ello, sentencias como la siguiente son válidas:
x = a = 2; // Primero se asigna a = 2, luego x = a
Operadores de asignación compuestos¶
En C, C++, Python, Java, etc. son muy utilizados los operadores de asignación compuestos.
La idea es que si tenemos una sentencia del tipo a = a OP b;
,
donde OP
es típicamente uno de los operadores aritméticos,
podemos abreviadamente utilizar la alternativa a OP= b;
.
a += b; // equivale : a = a + b
a -= b; // equivale : a = a - b
a *= b; // equivale : a = a * b
a /= b; // equivale : a = a / b
a %= b; // equivale : a = a % b
Debe tenerse en cuenta que estos operadores no solo permiten escribir una sentencia de una forma más abreviada. Internamente, el compilador generará instrucciones más eficientes, ya que le estamos informando de que uno de los operandos será el destino final de la expresión evaluada.
Advertencia
Nótese que OP=
debe escribirse con los dos símbolos seguidos,
sin espacios en blanco.
a + = b; // ¡ERROR!