Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


2.7. El peligro de la asignación en un if

Cuidado con el operador de igualdad: hay que recordar que el formato es if (a==b) ... Si no nos damos cuenta y escribimos if (a=b), estaremos asignando a "a" el valor de "b".

Afortunadamente, la mayoría de los compiladores nos avisan con un mensaje parecido a "Possibly incorrect assignment" (que podríamos traducir por "posiblemente esta asignación es incorrecta") o "Possibly unintended assignment" (algo así como "es posible que no se pretendiese hacer esta asignación"). Aun así, sólo es un aviso, no un "error fatal", por lo que la compilación prosigue, y se genera un ejecutable, que puede que se comporte incorrectamente. Vamos a verlo con un ejemplo:

/*  ej020701.c                        */
/*  Asignación en vez de igualdad (1) */
/*  Ejemplo del apartado 2.7          */
/*  Curso de C, Nacho Cabanes         */

#include 

int main() 
{
    int n=0;

    if (n = 3)
        printf("n vale 3");
    else 
        printf("n vale 0");

    return 0;
}

En este caso, un primer vistazo nos puede hacer creer que se escribirá en pantalla "n vale 0", pero el comportamiento no es ése, sino que no se está comparando correctamente, sino asignando un valor a "n". Además, se trata de un valor distinto de cero, lo que provoca que el compilador tome la condición como verdadera y se escriba "n vale 3".

Otro ejemplo un poco más detallado y en el que el "if" hace que la variable tome el valor 0 (lo que hace que el compilador considere que la condición no se cumple), sería:

/*  ej020702.c                        */
/*  Asignación en vez de igualdad (2) */
/*  Ejemplo del apartado 2.7          */
/*  Curso de C, Nacho Cabanes         */

#include 

int main() 
{
    int numero;

    printf("Escriba un número: ");
    scanf("%d", &numero);
    if (numero < 0)
        printf("El número es negativo.");
    else 
        if (numero = 0)
            printf("El número es cero.");
        else
            printf("El número es positivo.");

    return 0;
}

En este caso, si tecleamos un número negativo, se comprueba la primera condición, se ve que es correcta y se termina sin problemas. Pero si se teclea cualquier otra cosa (0 o positivo), la expresión "if (numero=0)" no comprueba su valor, sino que le asigna un valor 0 (falso), por lo que siempre se realiza la acción correspondiente a el "caso contrario" (else): siempre se escribe "El número es positivo"... ¡aunque hayamos tecleado un 0!

Y si esto es un error, ¿por qué el compilador "avisa" en vez de detener la compilación y mostrar un "error fatal"? Pues porque no tiene por qué ser necesariamente un error. Por ejemplo, podemos hacer

   a = b;
   if (a > 2) ...

o bien

   if ((a=b) > 2) ...

Es decir, en la misma orden asignamos el valor y luego comparamos. En este caso, la asignación dentro del "if" sería correcta.

Una forma simple de evitar este riesgo es escribir las comparaciones al revés: en vez de escribir

if (opcion == 2)  ...

podemos situar en primer lugar el número y en segundo lugar la variable:

if (2 == opcion)  ...

En este segundo caso, si olvidamos poner dos símbolos de "igual" y escribimos "if (2 = opcion)", se trata de una construcción no válida (no se puede cambiar el valor de un número) y el programa no compilaría. Lógicamente, este "truco" no sirve cuando comparamos dos variables, sólo cuando se trata de una variable y de un valor inmediato.


Ejercicios resueltos:

¿Qué escribiría en pantalla este fragmento de código?

int x = 5;  if (x==5) printf("%d", x);

Respuesta: x vale 5, luego se cumple la condición y se escribe un 5.


¿Qué escribiría en pantalla este fragmento de código?

int x = 5;  if (x) printf("Si"); else printf("No");

Respuesta: x vale 5, luego la condición se evalúa como verdadera y se escribe Si.


¿Qué escribiría en pantalla este fragmento de código?

int x = 0;  if (x=5) printf("Si"); else printf("No");

Respuesta: no hemos escrito una comparación dentro de "if", sino una asignación. Por tanto, lo que hay escrito dentro del paréntesis se evalúa como verdadero (distinto de cero) y se escribe Si.


¿Qué escribiría en pantalla este fragmento de código?

int x = 5;  if (x=0) printf("Si"); else printf("No");

Respuesta: de nuevo, no hemos escrito una comparación dentro de "if", sino una asignación. Por tanto, lo que hay escrito dentro del paréntesis se evalúa como falso (cero) y se escribe No.


¿Qué escribiría en pantalla este fragmento de código?

int x = 0;  if (x==5) printf("Si") else printf("No");

Respuesta: no compila, falta un punto y coma antes de "else".

Ejercicio propuesto 2.7.1: A partir del ejemplo ej020701 (n vale 3), cambia el orden de la comparación (3=n), para comprobar que no compila en ese caso, y posteriormente corrige el error.
Ejercicio propuesto 2.7.2: A partir del ejemplo ej020702 (El número es positivo), cambia el orden de la comparación (0 = numero), para comprobar que no compila con ese formato, y posteriormente corrige el error.