Herramientas de usuario

Herramientas del sitio


curso-cpp:estructuras-selectivas

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
curso-cpp:estructuras-selectivas [2016/10/06 20:27]
santo [El else]
curso-cpp:estructuras-selectivas [2017/10/29 19:28] (actual)
santo
Línea 1: Línea 1:
-======= Estructuras de control selectivas ​[En construcción] ​=======+======= Estructuras de control selectivas =======
  
 Hasta ahora, la lista de instrucciones de nuestro programa que se ejecutarán está **fija**: Esto es, siempre especificamos una lista de instrucciones,​ y **cada una de ellas** es ejecutada en orden, de arriba hacia abajo. Hasta ahora, la lista de instrucciones de nuestro programa que se ejecutarán está **fija**: Esto es, siempre especificamos una lista de instrucciones,​ y **cada una de ellas** es ejecutada en orden, de arriba hacia abajo.
Línea 13: Línea 13:
 La sintaxis (forma de escritura) de la instrucción if es la siguiente: La sintaxis (forma de escritura) de la instrucción if es la siguiente:
  
-<​code>​+<​code ​cpp>
 if (condicion) if (condicion)
 { {
     instruccion1;​     instruccion1;​
     instruccion2;​     instruccion2;​
-    ...+    ​//...
     instruccionFinal;​     instruccionFinal;​
 } }
Línea 27: Línea 27:
 Por ejemplo, el siguiente programa puede utilizarse para leer un número, y escribir en pantalla un mensaje de acuerdo a su signo: Por ejemplo, el siguiente programa puede utilizarse para leer un número, y escribir en pantalla un mensaje de acuerdo a su signo:
  
-<​code>​+<​code ​cpp>
 #include <​iostream>​ #include <​iostream>​
  
Línea 95: Línea 95:
 En efecto, cero es un número especial, el único entero que no es ni positivo ni negativo, y por lo tanto ''​0 < 0''​ y ''​0 > 0''​ son ambas **falsas**. Podemos entonces agregar este caso como un nuevo if en el programa: En efecto, cero es un número especial, el único entero que no es ni positivo ni negativo, y por lo tanto ''​0 < 0''​ y ''​0 > 0''​ son ambas **falsas**. Podemos entonces agregar este caso como un nuevo if en el programa:
  
-<​code>​+<​code ​cpp>
 #include <​iostream>​ #include <​iostream>​
  
Línea 134: Línea 134:
 Notar que en nuestra tercera condición, hemos utilizado por primera vez el operador ''​=='':​ Este operador no tiene **nada** que ver con el ''​='':​ Recordemos que el operador ''​=''​ se utiliza para la **asignación** de variables ("​meter valores en cajas"​). El ''​==''​ en cambio se utiliza para **expresar condiciones**,​ y funciona como la **igualdad matemática**. Notar que en nuestra tercera condición, hemos utilizado por primera vez el operador ''​=='':​ Este operador no tiene **nada** que ver con el ''​='':​ Recordemos que el operador ''​=''​ se utiliza para la **asignación** de variables ("​meter valores en cajas"​). El ''​==''​ en cambio se utiliza para **expresar condiciones**,​ y funciona como la **igualdad matemática**.
  
-El ''​==''​ es un ejemplo de los que de denominan //​operadores de comparación//​. Los veremos en más detalle muy pronto.+El ''​==''​ es un ejemplo de los que se denominan //​operadores de comparación//​. Los veremos en más detalle muy pronto.
  
 Veamos un segundo ejemplo de programa, que muestre un mensaje de acuerdo a la paridad del número ingresado: Veamos un segundo ejemplo de programa, que muestre un mensaje de acuerdo a la paridad del número ingresado:
  
-<​code>​+<​code ​cpp>
 int main() int main()
 { {
Línea 164: Línea 164:
 Es posible escribir lo siguiente: Es posible escribir lo siguiente:
  
-<​code>​+<​code ​cpp>
  
 if (condicion) if (condicion)
Línea 187: Línea 187:
 A continuación mostramos el ejemplo anterior de par o impar, reescrito utilizando la instrucción else: A continuación mostramos el ejemplo anterior de par o impar, reescrito utilizando la instrucción else:
  
-<​code>​+<​code ​cpp>
 int main() int main()
 { {
Línea 208: Línea 208:
  
 ==== Operadores de comparación ==== ==== Operadores de comparación ====
 +
 +Para expresar las condiciones anteriores, hemos utilizado los operadores <, >, e ==. Estos operadores se utilizan para expresar **condiciones**,​ mediante la **comparación** de otros dos valores. Así, ''​x > 10''​ expresa la condición de que el valor almacenado en ''​x''​ debe ser **mayor** que 10. Similarmente,​ ''​x + y == z''​ expresa la condición de que el valor almacenado en ''​x'',​ más el valor almacenado en ''​y'',​ debe ser **igual** al valor almacenado en ''​z''​.
 +
 +Estos operadores se llaman //​operadores de comparación//​. A continuación mostramos los más importantes operadores de comparación,​ junto a un texto que indica su significado:​
 +
 +<​code>​
 +== "Igual a"
 +!= "​Distinto de"
 +<  "Menor a"
 +>  "Mayor a"
 +<= "Menor o igual a"
 +>= "Mayor o igual a"
 +</​code>​
 +
 +Cada uno de estos operadores puede utilizarte para comparar los valores de dos expresiones,​ obteniéndose así una **condición** que puede utilizarse en un if. Recordar siempre que el operador de comparación "​==",​ y el operador de asignación "​="​ son completamente diferentes, y mezclarlos puede llevar a errores en el comportamiento del programa.
 +
 +Ya hemos usado estos operadores con valores de tipo int: en dicho caso, la comparación se realiza por valor numérico. También es posible utilizar los operadores de comparación con variables string (textos): En este caso, las palabras se ordenan en el orden del diccionario. El nombre técnico para el orden del diccionario (Donde primero van las palabras con A, luego con B, luego con C, etc) es "orden lexicográfico"​. Por ejemplo, tendremos que "​vaca"​ > "​sopa",​ y "​abcd"​ < "​bcda"​. Notar sin embargo que como ya mencionamos,​ a cada caracter (char) corresponde un valor numérico ASCII, y las mayúsculas y minúsculas tienen valores distintos. Como C++ ordena las variables de tipo string usando estos códigos, cadenas que mezclen mayúsculas y minúsculas no se ordenarán según el orden normal del diccionario,​ ya que en ASCII **todas las mayúsculas vienen antes que todas las minúsculas**. Así por ejemplo, si bien "​burro"​ > "​agua",​ tenemos que "​Burro"​ < "​agua",​ pues la '​B'​ viene antes que la '​a',​ que viene antes que la '​b'​.
  
 ==== Versión con una única instrucción ==== ==== Versión con una única instrucción ====
 +
 +Hemos visto que la sintaxis (escritura) completa del ''​if''​ tiene la siguiente forma:
 +
 +<code cpp>
 +if (condicion)
 +{
 +    instrucciones;​
 +}
 +else
 +{
 +    instrucciones;​
 +}
 +</​code>​
 +
 +Además, ya hemos mencionado que la parte del ''​else'',​ para especificar qué hacer cuando **no** se cumple la condición, es **opcional**. Una opción adicional que existe en C++ en el caso del ''​if''​ (o el ''​else''​),​ es la de no utilizar las llaves cuando el bloque de instrucciones que delimitan contiene una sola instrucción. En este caso, si no usamos llaves, C++ asumirá que **la primera** instrucción que sigue a continuación conforma el bloque completo.
 +
 +Veamos algunos ejemplos:
 +
 +<code cpp>
 +
 +// Escritura completa
 +if (x > 0)
 +{
 +    cout << "El numero es positivo"​ << endl;
 +}
 +cout << "Fin del programa"​ << endl;
 +
 +// Escritura sin llaves
 +if (x > 0)
 +    cout << "El numero es positivo"​ << endl;
 +cout << "Fin del programa"​ << endl;
 +
 +</​code>​
 +
 +Los dos ejemplos anteriores son equivalentes,​ ya que hay una sola instrucción entre llaves. Notemos en cambio que los siguientes dos ejemplos **no** son equivalentes:​
 +
 +<code cpp>
 +
 +// Escritura completa
 +if (x > 0)
 +{
 +    cout << "El numero ";
 +    cout << "es positivo"​ << endl;
 +}
 +cout << "Fin del programa"​ << endl;
 +
 +// Escritura sin llaves:
 +// CAMBIA EL SIGNIFICADO! ​
 +// Las llaves anteriores NO SE PUEDEN OMITIR.
 +if (x > 0)
 +    cout << "El numero ";
 +    cout << "es positivo"​ << endl;
 +cout << "Fin del programa"​ << endl;
 +
 +// La version anterior sin llaves equivale a esto:
 +if (x > 0)
 +{
 +    cout << "El numero ";
 +}
 +cout << "es positivo"​ << endl;
 +cout << "Fin del programa"​ << endl;
 +
 +
 +</​code>​
 +
 +En el ejemplo anterior, vemos que omitir las llaves cuando el bloque de instrucciones que queremos ejecutar tiene más de una instrucción es un error. Solamente es posible omitir las llaves, cuando el bloque tiene **una única instrucción**. **Ante la duda**, o posibilidad de confusión, es mejor dejar las llaves aunque se utilice una única instrucción,​ para evitar problemas.
 +
 +Existe un peligro más cuando omitimos las llaves, y este peligro es el resultado de que en C++ la parte ''​else''​ sea opcional. Supongamos un código como el siguiente:
 +
 +<code cpp>
 +// Ejemplo 1 (resulta correcto)
 +if (x > 0)
 +    if (x % 2 == 0)
 +        cout << "​Positivo par" << endl;
 +    else
 +        cout << "​Positivo impar" << endl;
 +   
 +// Ejemplo 2 (resulta incorrecto)
 +
 +if (x > 0)
 +    if (x % 2 == 0)
 +        cout << "​Positivo par" << endl;
 +else
 +    cout << "​Negativo"​ << endl;
 +
 +</​code>​
 +
 +Notemos que, más allá de los mensajes que se van a mostrar, la única diferencia entre el primer y el segundo ejemplo es la indentación (cantidad de espacios a la izquierda) del ''​else''​. Pero **al compilador no le importa la cantidad de espacios**. Por lo tanto, ambos casos son interpretados de idéntica manera. En este caso... ¿Corresponde para C++ el ''​else''​ al primer ''​if'',​ como querríamos en el ejemplo2, o corresponde al segundo, como querríamos en el ejemplo 1?
 +
 +La regla que sigue C++, que determina cómo resolver esta confusión cuando no se usan llaves en el ''​if'',​ es que un ''​else''​ en el código corresponde al ''​if''​ inmediatamente anterior. Es decir, el compilador interpreta la situación como querríamos en el ejemplo 1, con lo cual el ejemplo 2 nos resulta incorrecto. Para escribir lo que querríamos en el ejemplo 2, es necesario sí o sí utilizar llaves.
 +
 +Veamos a continuación entonces cómo escribir los ejemplos con la escritura completa con llaves:
 +
 +<code cpp>
 +// Ejemplo 1 (con llaves, correcto)
 +if (x > 0)
 +{
 +    if (x % 2 == 0)
 +    {
 +        cout << "​Positivo par" << endl;
 +    }
 +    else
 +    {
 +        cout << "​Positivo impar" << endl;
 +    }
 +}
 +   
 +// Ejemplo 2 (con llaves, correcto)
 +
 +if (x > 0)
 +{
 +    if (x % 2 == 0)
 +    {
 +        cout << "​Positivo par" << endl;
 +    }
 +}
 +else
 +{
 +    cout << "​Negativo"​ << endl;
 +}
 +
 +</​code>​
 +
 +Notar que ahora en el ejemplo 2, al tener todas las llaves, el compilador no puede confundirse y emparejar el ''​else''​ con el ''​if''​ interno, ya que ese ''​if''​ se encuentra **dentro** del bloque de instrucciones entre llaves, y por lo tanto no puede corresponderse con un ''​else''​ que está por fuera de las llaves.
 +
 +===== Ejercicios =====
 +
 +   * [[http://​juez.oia.unsam.edu.ar/#/​task/​multi_tres/​statement|Escribir un programa que lea un numero, y nos diga si es múltiplo de 3 o no.]]
 +   * [[http://​juez.oia.unsam.edu.ar/#/​task/​cual_va_primero/​statement|Escribir un programa que lea dos palabras, y nos diga cuál viene primero en el diccionario.]]
 +   * [[http://​juez.oia.unsam.edu.ar/#/​task/​es_bisiesto/​statement|Escribir un programa que lea un número de año, y nos diga si es bisiesto.]]
  
 ===== Operadores lógicos ===== ===== Operadores lógicos =====
  
-====El tipo bool =====+A veces, queremos expresar **condiciones compuestas**,​ en base a otras condiciones más simples. Los //​operadores lógicos// sirven para obtener tales condiciones. A continuación mostramos los operadores lógicos más comunes, junto con su nombre: 
 + 
 +<​code>​ 
 +&& "​and"​ 
 +|| "​or"​ 
 +!  "​not"​ 
 +</​code>​ 
 + 
 +El operador ''&&'',​ denominado "​and",​ se utiliza para formar una condición compuesta en la cual se exige que otras **dos** condiciones **se cumplan al mismo tiempo**. Por ejemplo, ''​x > 0 && x % 2 == 0''​ expresa la condición de que x sea un número par positivo, indicando que deben cumplirse tanto ''​x > 0''​ como ''​x % 2 == 0''​. ''​x > 0 && x < 0'',​ por ejemplo, denota una condición imposible de cumplir, ya que se pide que x sea positivo y negativo. 
 + 
 +El operador ''​||'',​ denominado "​or",​ se utiliza para formar una condición compuesta en la cual se exige que **al menos una** de otras **dos** condiciones se cumpla. Así por ejemplo, cero será el único número que no cumple la condición ''​x > 0 || x < 0'':​ En esta condición se pide que x sea positivo o negativo. El único número que no cumple ninguna de ellas es el cero. Otro ejemplo es ''​x % 2 == 0 || x % 3 == 0'',​ en el cual se pide que x sea múltiplo de 2 o de 3. Además, si x resulta ser múltiplo de ambos (como por ejemplo, 12), la condición igualmente se cumple, pues con una sola que se cumpla basta, y si se cumplen las dos "​mejor"​. 
 + 
 +Finalmente, el operador ! se usa para invertir una condición dada, que generalmente deberá encerrarse entre paréntesis. Por ejemplo, ''​!(x < 0)''​ es completamente equivalente a ''​(x >= 0)''​. Por otro lado, ''​!(x % 2 == 0 || x % 3 == 0)'',​ por ejemplo, estaría negando la condición anterior de que el número x sea múltiplo de 2 o de 3, y por lo tanto esta condición solamente será cierta cuando el número no sea múltiplo ni de 2 ni de 3. 
 + 
 +Utilizando estos operadores lógicos, podemos muchas veces resumir largas cadenas de ifs, en una sola condición compuesta más clara. Veamos por ejemplo el siguiente ejemplo para decidir si un año es bisiesto: 
 + 
 +<code cpp> 
 +#include <​iostream>​ 
 + 
 +using namespace std; 
 + 
 +int main() 
 +
 +    int year; 
 +    cin >> year; 
 +    if (year % 400 == 0) 
 +        cout << "Es bisiesto."​ << endl; 
 +    else 
 +    { 
 +        // En este caso, no es multiplo de 400 
 +        if (year % 100 == 0) 
 +            cout << "No es bisiesto " << endl; 
 +        else 
 +        { 
 +            // En este caso, no es multiplo de 100 
 +            if (year % 4 == 0) 
 +                cout << "Es bisiesto."​ << endl; 
 +            else 
 +                cout << "No es bisiesto."​ << endl; 
 +        } 
 +    } 
 +    return 0; 
 +
 + 
 +</​code>​ 
 + 
 +Si bien es correcto, este código puede resumirse en el siguiente mucho más claro, utilizando expresiones lógicas: 
 + 
 +<code cpp> 
 +#include <​iostream>​ 
 + 
 +using namespace std; 
 + 
 +int main() 
 +
 +    int year; 
 +    cin >> year; 
 +    if (year % 400 == 0 || (year % 4 =0 && year % 100 !0)) 
 +        cout << "Es bisiesto."​ << endl; 
 +    else 
 +        cout << "No es bisiesto " << endl; 
 +    return 0; 
 +
 + 
 +</​code>​ 
 + 
 +Notar que encerramos entre paréntesis la condición ''​(year % 4 == 0 && year % 100 !0)''​. Siempre es conveniente utilizar paréntesis para indicar el orden de las operaciones lógicas, cuando encadenamos una mezcla de operaciones ''​||''​ y ''&&''​.
  
 ===== El tipo bool ===== ===== El tipo bool =====
  
 +Ya hemos visto los tipos ''​int'',​ ''​string''​ y ''​char''​. Veremos ahora un tipo de datos adicional: El tipo ''​bool''​.
 +
 +Un ''​bool''​ representa el **resultado** de analizar si una condición es **cierta o falsa**. Por lo tanto, un valor ''​bool''​ representa un sí o un no. En C++, el sí se escribe ''​true''​ (del inglés "​verdadero"​) y el no se escribe ''​false''​ (del inglés, "​falso"​).
 +
 +Ahora podemos entender que todos los operadores de comparación que vimos, así como todos los operadores lógicos, operan con expresiones y producen resultados de tipo ''​bool'':​ ''​true''​ cuando la condición analizada es cierta, y ''​false''​ cuando la condición analizada no lo es.
 +
 +Por ejemplo, en el caso de los operadores de comparación,​ ''​1 < 2''​ da por resultado ''​true'',​ que es un valor de tipo ''​bool''​. ''​1 == 2''​ es otro valor de tipo ''​bool'',​ que será ''​false''​. Como con cualquier otro tipo de datos, podemos declarar variables ''​bool'':​
 +
 +<code cpp>
 +bool cond1 = 1 == 2;
 +bool cond2 = 1 < 2;
 +if (cond1)
 +    cout << "Esto no se ejecuta"​ << endl;
 +if (cond2)
 +    cout << "Esto si se ejecuta"​ << endl;
 +if (cond1 || cond2)
 +    cout << "Esto si se ejecuta"​ << endl;
 +if (cond1 && cond2)
 +    cout << "Esto no se ejecuta"​ << endl;
 +</​code>​
 +
 +En este ejemplo, vemos que las operaciones lógicas ''​||''​ y ''&&''​ operan con 2 valores de tipo bool: ''​||''​ da por resultado ''​true''​ cuando al menos uno de los operandos lo es, y ''&&''​ devuelve ''​true''​ solamente cuando ambos operandos lo son.
 +
 +Además, en este ejemplo vemos que lo que hemos llamado ''​condición'',​ y que se debe colocar entre paréntesis en el ''​if'',​ en realidad puede ser cualquier **expresión de tipo bool**. Esto permite guardar valores **bool** intermedios en variables, y usarlos libremente en expresiones compuestas mediante operadores lógicos y de comparación.
 +===== Más ejercicios =====
 +
 +    * [[http://​juez.oia.unsam.edu.ar/#/​task/​tri_sort/​statement|Escribir un programa que lea tres números, y los vuelva a imprimir pero ordenados de menor a mayor.]]
 +    * [[http://​juez.oia.unsam.edu.ar/#/​task/​la_hora/​statement|Escribir un programa que lea una hora en formato de 24 horas (exactamente 5 caracteres) y la imprima en forma AM / PM.]] Ejemplos:<​code>​
 +            23:12 imprime 11:12 PM
 +            10:15 imprime 10:15 AM
 +            12:15 imprime 12:15 PM
 +            00:15 imprime 12:15 AM</​code>​
 +    * [[http://​juez.oia.unsam.edu.ar/#/​task/​productis/​statement|Leer dos numeros de hasta 2 digitos, e imprimir una "​cuenta"​ del producto.]] La cuenta debe estar bien alineada a derecha. Ejemplos: <​code>​
 +            Si vienen 12 y 5,
 +               12
 +             ​x ​ 5
 +             ----
 +               60
 +            Si vienen 10 y 10,
 +               10
 +             x 10
 +             ----
 +              100
 +            Si vienen 50 y 60,
 +               50
 +             x 60
 +             ----
 +             3000
 +            Si vienen 0 y 99,
 +                0
 +             x 99
 +             ----
 +                0</​code>​
curso-cpp/estructuras-selectivas.1475785636.txt.gz · Última modificación: 2016/10/06 20:27 por santo