AnteriorPosterior

3. Condiciones (1: if)

Por: Nacho Cabanes
Actualizado: 25-04-2019 20:16
Tiempo de lectura estimado: 18 min.

 

C++

3. Condiciones

3.1. if

Vamos a ver cómo podemos comprobar si se cumplen condiciones. La primera construcción que usaremos será "si ... entonces ...". El formato equivalente en C++ es

if (condición) sentencia;

Vamos a verlo con un ejemplo:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.01:
// Condiciones con if 
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero>0)  cout << "El numero es positivo.";
 
    return 0;
}

Nota: para comprobar si un valor numérico es mayor que otro, usamos el símbolo “>”, como se ve en este ejemplo. Para ver si dos valores son iguales, usaremos dos símbolos de “igual”: if (numero==0). Las demás posibilidades las veremos algo más adelante. En todos los casos, la condición que queremos comprobar deberá indicarse entre paréntesis.

Ejercicios propuestos:

  • (3.1.1) Crear un programa que pida al usuario un número entero y diga si es par (pista: habrá que comprobar si el resto que se obtiene al dividir entre dos es cero: if (x % 2 == 0) …).
  • (3.1.2) Crear un programa que pida al usuario dos números enteros y diga cual es el mayor de ellos.
  • (3.1.3) Crear un programa que pida al usuario dos números enteros y diga si el primero es múltiplo del segundo (pista: igual que antes, habrá que ver si el resto de la división es cero: a % b == 0).

3.2. if y sentencias compuestas

La "sentencia" que se ejecuta si se cumple la condición puede ser una sentencia simple o una compuesta. Las sentencias compuestas se forman agrupando varias sentencias simples entre llaves ( { y } ):

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.02:
// Condiciones con if (2)
//   Sentencias compuestas
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero>0)  
    {  
        cout << "El numero es positivo." << endl;
        cout << "Recuerda que tambien puedes usar negativos." << endl;
    }  // Aqui acaba el "if"
 
    return 0;
}    // Aqui acaba el cuerpo del programa

En este caso, si el número es negativo, se hacen dos cosas: escribir un texto y luego... ¡escribir otro! (Claramente, en este ejemplo, esos dos “cout” podrían ser uno solo; más adelante iremos encontrando casos en los que necesitemos hacer cosas “más serias” dentro de una sentencia compuesta).

Se pueden incluir siempre las llaves después de un "if", como medida de seguridad: un fallo frecuente es escribir una única sentencia tras "if", sin llaves, luego añadir una segunda sentencia y olvidar las llaves... de modo que la segunda orden no se ejecutará si se cumple la condición, sino siempre, como en este ejemplo:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.02b:
// Condiciones con if (2b)
//   Sentencias compuestas... incorrectas
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero>0)  
        cout << "El numero es positivo." << endl;
        cout << "Recuerda que tambien puedes usar negativos." << endl;
 
    return 0;
}

En este caso, siempre se nos dirá "Recuerde que también puede usar negativos", incluso cuando hemos tecleado un número negativo. En un vistazo rápido, vemos las dos sentencias tabuladas a la derecha y tendemos a pensar que las dos dependen del "if", pero no es así. Se trata de un error difícil de detectar. Por eso, muchos autores recomiendan incluir siempre las llaves tras un "if", e incluso algún lenguaje de programación moderno obliga a que siempre sea así.

3.3. Operadores relacionales: <, <=, >, >=, ==, !=

Hemos visto que el símbolo “>” es el que se usa para comprobar si un número es mayor que otro. El símbolo de “menor que” también es sencillo, pero los demás son un poco menos evidentes, así que vamos a verlos:

Operador Operación
< Menor que
> Mayor que
<= Menor o igual que
>= Mayor o igual que
== Igual a
!= No igual a (distinto de)

Y un ejemplo:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.03:
// Condiciones con if (3): distinto de
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero!=0)  cout << "El numero no es cero.";
 
    return 0;
}

Los operadores sólo se pueden usar tal y como aparecen en esa tabla. Por ejemplo, no es un operador válido “!<” para expresar que un número no es menor que otro.

Ejercicios propuestos:

  • (3.3.1) Crear un programa que multiplique dos números enteros de la siguiente forma: pedirá al usuario un primer número entero. Si el número que se que teclee es 0, escribirá en pantalla “El producto de 0 por cualquier número es 0”. Si se ha tecleado un número distinto de cero, se pedirá al usuario un segundo número y se mostrará el producto de ambos.
  • (3.3.2) Crear un programa que pida al usuario dos números reales. Si el segundo no es cero, mostrará el resultado de dividir entre el primero y el segundo. Por el contrario, si el segundo número es cero, escribirá “Error: No se puede dividir entre cero”.

3.4. if-else

Podemos indicar lo que queremos que ocurra en caso de que no se cumpla la condición, usando la orden “else” (en caso contrario), así:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.04:
// Condiciones con if y else
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero>0)  cout << "El numero es positivo.";
        else  cout << "El numero es cero o negativo.";
 
    return 0;  
}

Podríamos intentar evitar el uso de “else” si utilizamos un “if” a continuación de otro, así:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.05:
// Intentando esquivar "else"
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero>0)  cout << "El numero es positivo.";
    if (numero<=0) cout << "El numero es cero o negativo.";
 
    return 0;
}

Pero el comportamiento no es el mismo: en el primer caso (ejemplo 03.04) se mira si el valor es positivo; si no lo es, se pasa a la segunda orden, pero si lo es, el programa ya ha terminado. En el segundo caso (ejemplo 03.05), aunque el número sea positivo, se vuelve a realizar la segunda comprobación para ver si es negativo o cero, por lo que el programa es algo más lento.

Podemos enlazar los “if” usando “else”, para decir “si no se cumple esta condición, mira a ver si se cumple esta otra”:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.06
// Condiciones con if encadenados
 
#include <iostream>
using namespace std;
 
int main()
{
    int numero;
 
    cout << "Escriba un numero: ";
    cin >> numero;
    if (numero < 0)
        cout << "El numero es negativo.";
    else 
        if (numero == 0)
            cout << "El numero es cero.";
        else
            cout << "El numero es positivo.";
 
    return 0;
}

Ejercicio propuesto :

  • (3.4.1) Mejorar la solución a los dos ejercicios del apartado anterior, usando “else”.

3.5. Operadores lógicos: &&, ||, !

Estas condiciones se puede encadenar con “y”, “o”, etc., que se indican de la siguiente forma

Operador Significado
&& Y
|| O
! No

De modo que podremos escribir cosas como

if ((opcion==1) && (usuario==2)) ...
if ((opcion==1) || (opcion==3)) ...
if ((!(opcion==opcCorrecta)) || (tecla==teclaEscape)) ...

La siguiente forma de escribir una condición es incorrecta (y es un error muy frecuente en los que empiezan a programar en C y en C++):

if ( opcion1 || opcion2 == 3 ) ...

porque la forma correcta de comprobar si la variable “opcion1” o bien “opcion2” valen “3” sería ésta:

if (( opcion1 == 3 ) || ( opcion2 == 3 )) ... 

Ejercicios propuestos :

  • (3.5.1) Crear un programa que pida una letra al usuario y diga si se trata de una vocal.
  • (3.5.2) Crear un programa que pida al usuario dos números enteros y diga “Uno de los números es positivo”, “Los dos números son positivos” o bien “Ninguno de los números es positivo”, según corresponda.
  • (3.5.3) Crear un programa que pida al usuario tres números reales y muestre cuál es el mayor de los tres.
  • (3.5.4) Crear un programa que pida al usuario dos números enteros cortos y diga si son iguales o, en caso contrario, cuál es el mayor de ellos.

3.6. Cómo funciona realmente la condición en un “if”

Como suele ocurrir en C++, lo que hemos visto tiene más miga de la que parece: una condición cuyo resultado sea “falso” nos devolverá un 0, y otra cuyo resultado sea “verdadero” devolverá el valor 1:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.07:
// "Valor de verdad" de una condición
 
#include <iostream>
using namespace std;
 
int main() 
{
    cout << "2==3 vale " << (2==3);  // Escribe 0
    cout << "2!=3 vale " << (2!=3);  // Escribe 1
 
    return 0;
}

En general, si la “condición” de un if es algo que valga 0, se considerará que la condición es falsa (no se cumple), y si es algo distinto de cero, se considerará que la condición es verdadera (sí se cumple). Eso nos permite hacer cosas como ésta:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.08:
// Condiciones con if (8): valor numérico
 
#include <iostream>
using namespace std;
 
int main() 
{
    int numero;
 
    cout << "Escribe un numero: ";
    cin >> numero;
    if (numero!=0)  // Comparacion normal
        cout << "El numero no es cero.";
    if (numero)     // Comparacion "con truco"
        cout << "Y sigue sin ser cero.";
 
    return 0;
} 

En este ejemplo, la expresión “if (numero)” se fijará en el valor de la variable “numero”. Si es distinto de cero, se considerará que la condición es correcta, y se ejecutará la sentencia correspondiente (el “cout”). En cambio, si la variable “numero” vale 0, es considera que la condición es falsa, y no se sigue analizando.

En general, es preferible evitar este tipo de construcciones. Resulta mucho más legible algo como “if (numero!=0)” que “if(numero)”.

3.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) estamos 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, la compilación prosigue, y se genera un ejecutable, que puede que se comporte incorrectamente. Vamos a verlo con un ejemplo:

// Introducción a C++, Nacho Cabanes
// Ejemplo 03.09:
// Condiciones con if:
//   Comportamiento incorrecto
 
#include <iostream>
using namespace std;
 
int main()
{
    int numero;
 
    cout << "Escriba un numero: ";
    cin >> numero;
    if (numero < 0)
        cout << "El numero es negativo.";
    else 
        if (numero = 0)
            cout << "El numero es cero.";
        else
            cout << "El numero 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 parar y dar un error “serio”? Pues porque no tiene por qué ser necesariamente un error: podemos hacer

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

o bien

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

Es decir, en la misma orden asignamos el valor y comparamos (algo parecido a lo que hacíamos con “b = ++a”, por ejemplo). En este caso, la asignación dentro del “if” sería correcta.

Ejercicios resueltos:

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

int x = 5; if (x==5) cout << 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) cout << "Si"; else cout << "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) cout << "Si"; else cout << "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) cout << "Si"; else cout << "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) cout << "Si" else cout << "No";

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

115112 visitas desde el 20-04-2019

AnteriorPosterior