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

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!