Programando desde 0: 06- Condiciones booleanas y selección.
12 Último

Programando desde 0: 06- Condiciones booleanas y selección.

      • 322
      • mensajes
      • miembro desde
      • 07/02/07
    18/12/2011
    #1 Programando desde 0: 06- Condiciones booleanas y selección.
    LECCIÓN 6: Condiciones booleanas y Selección

    Ya tuvimos un vistazo de esto en la lección anterior. Ahora volveremos a retomar el mismo tema. Comenzaremos a ver la instrucción IF...THEN tal como ya lo hicimos, la cual sirve para elegir un camino en caso de que una condición sea verdadera. Luego veremos como utilizar la instrucción IF...THEN...ELSE que sirve para tomar un camino en caso de que una condición sea verdadera u otro en caso contrario.

    Trabajaremos con la anidación de estas instrucciones, o sea, con la composición de las mismas. Esto es, usar varias instrucciones IF juntas, para finalmente ver la instrucción CASE...ELSE que sirve para tomar distintos caminos según las condiciones dadas.

    De este modo nuestros programas podrán hacer una cosa u otra, abriendo un abanico de posibilidades nuevas. Sin embargo, aún estaremos muy limitados porque nos hace falta la repetición, tema que se vendrá en la lección siguiente a esta.

    ----------------------------------------------------------------------------------

    Instrucción IF...THEN:

    Vimos en la lección anterior que la sintaxis genérica de esta instrucción es
    Código:
    If condicion then
       instruccion;
    Vimos además que la condición es algo del tipo BOOBLEAN, o sea, algo que puede ser verdadero o falso (TRUE, FALSE).

    Estas condiciones se verán generalmente con comparaciones tales como las que ejemplifiqué en la lección anterior. Sin embargo, dichas pueden no ser numéricas, o sea, está bien comparar si un numero es mayor que otro, menor o igual, pero podemos hacer lo mismo con los demás tipos de datos.

    Podemos ver si dos Strings son iguales o no, si dos caracteres son iguales o si uno es mayor que otro tal como los números.

    Los caracteres están en un cierto orden que para FreePascal está designado según la Tabla Ascii, pero esto lo veremos más adelante. Lo que diré ahora que las letras están de menor a mayor o sea que

    'a' es menor que 'b' que es menor que 'c', etc. De modo que es posible preguntar

    'a'<'j' lo cual dará TRUE como resultado porque la 'a' es menor que la 'j' en el orden.

    Las letras mayúsculas están antes que las minúsculas y también respetan el orden alfabético, por tanto

    'A'<'B'<'C' etc

    y además 'A'<'a'. De este modo, al igual que los número están en este orden

    0 1 2 3 4 5 6 7 8 9 10 11 12 13....

    las letras están en este

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g ...

    Siempre que nos referimos a caracteres debemos colocarlos entre comillas simples al igual que a los strings. Un caracter corresponde al tipo char, cuando es más de un caracter entonces pasa a ser string.

    'a' es del tipo char al igual que 'B' porque ambos son un solo caracter, pero 'aB' no porque son dos caracteres juntos, por tanto es un String.

    Veamos un ejemplo sencillo del uso del tipo char, donde el usuario ingresará dos letras en la entrada y luego las comparamos.

    Código:
    1  PROGRAM Caracteres;
    2  
    3  VAR
    4     letra1, letra2: char;  //Una variable para cada letra.
    5  
    6  BEGIN
    7     Write('Ingrese dos letras separadas por espacios: ');
    8     Readln(letra1,letra2);  //Leemos la entrada y la asignamos a las variables.
    9     Writeln;   //Dejamos una línea en blanco.
    10   
    11   If letra1<=letra2 then
    12      writeln('La primera letra es menor o igual a la segunda');
    13  
    14   If letra1>=letra2 then
    15      writeln('La primera letra es mayor o igual a la segunda');
    16
    17   Readln;
    18 END.
    Este programa es bien sencillo. Tenemos dos variables del tipo char, letra1 y letra2. Las leemos tal como si fueran variables numéricas.

    En la línea 11 tenemos nuestra primera sentencia IF, donde si la primera letra es menor o igual que la segunda escribimos el mensaje informativo.

    En la línea 14 tenemos otra sentencia IF con una condición inversa a la primera, o sea, si letra1 es mayor o igual a letra2 escribimos el mensaje.

    Prueben este programa ingresando letras. Si ingresan strings el programa se caerá porque las variables son char.

    ¿Qué pasa si se ingresan letras iguales? Aparecerán los dos mensajes en pantalla. Esto es porque las condiciones de ambos IF contemplan la posibilidad de que las letras sean iguales, o sea

    'a'<='a' es verdadero porque la letra a no es menor que la misma a pero sí es igual.

    'a'>='a' también es verdadero por la misma razón.

    -------------

    ¿Qué pasa si se ingresan números de una cifra en la entrada? ¿Se cae el programa? Pues no. Y ustedes dirán ¿por qué no si los números no son letras?
    El programa no caerá porque el tipo char admite caracteres cualesquiera de la entrada o asignación, entonces, hay que tener presente que no es lo mismo el número 1 que el caracter '1'.

    Si tengo una variable a del tipo integer y una variable b del tipo char yo puedo hacer estas asignaciones:

    Código:
    a:= 1;
    b:= '1';
    Noten que para la variable b asigné el 1 entre comillas simples, o sea, el caracter 1, no el número. Un caracter es un símbolo y nada más, tal como lo son las letras, los números y todo otro caracter extraño que se les ocurra.

    Si yo hago

    write(a+2) mostraré en pantalla el número entero 3 porque a valía 1.

    Sin embargo, si hago write(b+2) tengo un error en tiempo de compilación porque no puedo sumarle el número 2 al caracter '1', es como intentar sumarle 2 a una letra.

    Tengan mucho ojo con esto.

    NOTA: Vean que al final de este programa he colocado una instrucción

    Código:
    readln;
    sin parámetros ni nada. Normalmente read y readln se usan para leer un valor de la entrada y guardarlo en una variable, sin embargo si los usamos sin parámetros, el programa quedará a la espera de que se presione ENTER para continuar ya que lea lo que lea no lo guardará en ningún lado.
    De este modo el programa queda detenido al final permitiéndonos visualizar los resultados de una forma más sencilla. Sin embargo no es correcto, por lo tanto, lo mejor es que usen esta sutileza solo mientras prueban sus programas y luego, cuando estan seguros de que anda bien, la borran.

    -------------------------------------------------------------------------------------

    Instrucción IF...THEN...ELSE:

    Esta instrucción funciona casi igual que la IF...THEN, pero con una diferencia crucial. La sentencia

    Código:
    If condicion then
       instruccion;
    la instruccion se ejecutaba solo si la condicion era verdadera, o sea TRUE. En caso contrario no se ejecuta nada y el programa continúa su curso. Sin embargo, la instrucción IF...THEN...ELSE se ejutará siempre. Veamos, su sintaxis es así

    Código:
    If condicion then
       instruccion1
    Else
       instruccion2;
    Esto significa SI pasa tal cosa HAZ esta instruccion, SINO HAZ esta otra. O sea, si la condicion es verdadera se ejecuta la instruccion1 tal y como ya han visto, y se omitirá la instrucción luego del ELSE. Si la condición es falsa no se hará la instruccion1 y se hará automáticamente la instruccion2.

    O sea, le estamos diciendo al IF lo que debe hacer si su condicion es falsa. Antes solo le decíamos que hacer si era verdadera, ahora tiene las dos opciones, por lo tanto, algo se ejecutará sí o sí.

    Noten que la instruccion1 no termina en punto y coma (;). Nunca antes de un ELSE que forma parte de un IF debe ir un punto y coma porque el compilador creerá que es un IF común como el que vimos al principio.

    Para el ejemplo anterior, teniendo las variables letra1 y letra2 puedo escribir esto

    Código:
    If letra1<=letra2 then
       writeln('La primera letra es menor o igual que la segunda')
    Else
       writeln('La primera letra es mayor que la segunda');
    Veamos un ejemplo, primero solo con IF...THEN, donde se le pedirá al usuario que ingrese su edad, asumiremos que se ingresarán números enteros. Si la edad es mayor a 50 años le decimos que es un viejo, en caso contrario le decimos que es joven:

    Código:
    1 PROGRAM viejo;
    2
    3 Var
    4    edad: integer; //Variable para guardar la edad.
    5
    6 BEGIN
    7    //Mostramos mensaje y leemos la edad.
    8    write('Ingrese su edad: ');
    9    readln(edad);
    10
    11  //Mostramos lo mismo que ya ingresó.
    12  writeln('Usted tiene ',edad,' años.');
    13
    14  //Si tiene más de 50 años le decimos viejo.
    15  If edad>50 then
    16      writeln('Usted es un viejo');
    17
    18  //Si tiene menos de 50 o 50 justito, le decimos joven.
    19  If edad<=50 then
    20     writeln('Usted es joven');
    21
    22 END.
    Hemos usado dos sentencias IF, una contempla lo que la otra no, o sea que o se ejecuta una o la otra. Sin embargo, aunque esto se puede hacer, no es lo correcto porque en futuros programas mucho mas complejos se complicará, además hace que el código sea menos comprensible. Los dos If anteriores se resumen en este

    Código:
    If edad>50 then
       writeln('Usted es un viejo')
    Else
       writeln('Usted es joven');
    ------------------------------------------------------------------------------------

    Anidación de la instrucción If…then:

    Es posible colocar un if dentro de otro if. A esto se lo conoce como anidación y se usa a muy menudo. Sin embargo hay que tener mucho cuidado de hacerlo bien o podría darse que nosotros creemos que el programa tomará cierto camino cuando en realidad no lo hará. Veremos un ejemplo de eso luego del de a continuación:

    Veamos un ejemplo en el que se nos pedirá la edad dos veces. Si ingresamos una edad mayor a 50 y otra menor nos dirá que somos viejos jóvenes.
    Código:
    1 PROGRAM anidacion;
    2
    3 Var
    4    edad1, edad2: integer;
    5
    6 BEGIN
    7    Write(‘Ingresa tu edad: ‘);
    8    Readln(edad1);
    9    Write(‘Ingresa tu edad nuevamente: ‘);
    10   Readln(edad2);
    11
    12   If edad1>50 then
    13     If edad2<50 then
    14        Writeln(‘Eres un viejo joven’);
    15
    16 END.
    Como vemos, nuestro programa nos pide el ingreso de números enteros que corresponden a nuestra edad. En la línea 12 decimos si el valor en edad1 es mayor a 50 entonces si el valor en edad2 es menor a 50 escribe ‘Eres un viejo joven’.

    Ahora bien, si edad1 es menor a 50 entonces no pasa nada, porque el segundo If está dentro del primero y por ende, si la condición de este no se cumple no entraremos en él.

    -------------------------------------------------------------------------------------

    Anidación de un if…then con un if…then…else:

    Es posible hacer todas las anidaciones que se quieran, sin embargo como ya dije antes, debemos tener cuidado. Aquí daré un ejemplo de una anidación que nosotros podríamos interpretar de forma errónea.

    Código:
    1 PROGRAM anidacion2;
    2
    3 Var
    4    edad1, edad2: integer;
    5
    6 BEGIN
    7    Write(‘Ingresa tu edad: ’);
    8    Readln(edad1);
    9    Write(‘Ingresa nuevamente tu edad: ‘);
    10   Readln(edad2);
    11
    12   If edad1>50 then
    13     If edad1=edad2 then
    14        Writeln(‘Eres un viejo’)
    15   else
    16      Writeln(‘Eres joven’);
    17
    18 END.
    En este ejemplo uno podría interpretar que si tenemos más de 50 años y además ingresamos las dos veces la misma edad aparecerá el mensaje ‘Eres un viejo’, y si edad1 era menor a 50 nos aparecerá el mensaje ‘Eres joven’. Sin embargo no es así, esa instrucción se fijará si nuestra edad es mayor a 50 y solo si eso es cierto luego verá si ambas edades eran iguales, si es así aparecerá el mensaje ‘Eres un viejo’ y si no aparecerá el mensaje ‘Eres joven’. La correcta indentación de esa instrucción es la siguiente:
    Código:
    If edad1>50 then
       If edad1=edad2 then
          Wirteln(‘Eres un viejo’)
       else
          Writeln(‘Eres un joven’);
    Como ven, solo se ejecutará esto si edad1>50 resulta ser true.
    La forma correcta de escribir esta instrucción para obtener el resultado que interpretábamos anteriormente sería:

    Código:
    If edad1>50 then
    begin
       If edad1=edad2 then
          Wirteln(‘Eres un viejo’);
    end
       else
          Writeln(‘Eres un joven’);
    Como ven, hemos encerrado entre begin y end la segunda instrucción if. Esto hace que todo lo que esté dentro del área abarcada por esas dos palabras sea como una sola instrucción para el programa, a pesar de que allí dentro podemos poner todas las que queramos. De no hacer esto, el else formaría parte del segundo if y no del primero. Debemos recordar que un else cierra siempre al if que se encuentre más próximo a él. Para quebrar esto debemos usar beginy end.

    Los delimitantes begin y end se usan para indicar que al tomar cierto flujo de ejecución dada una condición el programa debe efectuar muchas instrucciones. No serviría de mucho que por cada if que usemos solo podamos dictar una instrucción. La sintaxis genérica sería la siguiente:

    Código:
    If condicion then
    begin
       Instruccion1;
       Instruccion2;
       .
       .
       .
       InstruccionN;
    end
    else
    begin
       Instruccion1;
       Instruccion2;
       .
       .
       .
       InstruccionN;
    end;
    Vean que también es posible usar los delimitadores begin y end para la instrucción else del if. Estos begin y end forman lo que llamamos bloques de instrucciones y difieren del begin y end principales ya que estos forman un único bloque que es el programa completo. Luego de un end va enseguida un punto y coma que indica el final del bloque y no un punto como en el caso del end principal.

    Notar que el end anterior al else no finaliza con punto y coma. Esto se debe a lo que ya expliqué antes. Recordar que nunca, antes de una instrucción else que forma parte de un if debe ir colocado un punto y coma.

    ------------------------------------------------------------------------------------

    Condiciones compuestas:

    Hasta ahora hemos visto como dada una condición específica el programa tomará un camino u otro para realizar sus tareas. Sin embargo normalmente deben cumplirse varias condiciones para que un programa tome un camino u otro. Aquí entramos a componer condiciones, o sea, a decir cosas como: Si pasa tal cosa y tal otra has esta tarea o si pasa tal otra cosa has esta.
    Aprenderemos a usar los operadores booleanos para componer condiciones.

    Veamos un ejemplo parecido al anterior:
    Código:
    1 PROGRAM anidacion2;
    2
    3 Var
    4    edad1, edad2: integer;
    5
    6 BEGIN
    7    Write(‘Ingresa tu edad: ’);
    8    Readln(edad1);
    9    Write(‘Ingresa nuevamente tu edad: ‘);
    10   Readln(edad2);
    11
    12   If (edad1>50) and (edad1=edad2) then
    13      Writeln(‘Eres un viejo’)
    14   else
    15      Writeln(‘O eres joven o mentiroso’);
    16
    17 END.
    Aquí vemos que en la instrucción IF hay dos condiciones entre paréntesis unidas por la palabra reservada AND. Esto significa que se ejecutará la instrucción del IF si ambas condiciones son verdaderas, o sea, si se cumple a la vez que edad1>50 y que edad1=edad2. Basta con que una de ellas sea falsa para que no se ejecute la instrucción del IF y se pase a la del ELSE. En ese caso no sabremos si sucedió porque el usuario era joven o si era un mentiroso que ingresó dos edades diferentes.

    Esta es una composición de condiciones que forman una condición total. El AND forma esta condición evaluando las dos pequeñas, entonces si ambas son verdaderas a la vez la condición AND devuelve TRUE.

    Estas composiciones son evaluadas por Free Pascal con el método conocido como circuito corto. Esto es que, si la primera condición del AND es falsa, ya no se evaluará la segunda porque aunque esta fuera verdadera la condición total resulta falsa. Así nacen las tablas de verdad. AND en inglés significa Y.

    Si nosotros quisiéramos haber dicho que se ejecute el IF si la primera condición ó la otra eran verdaderas deberíamos haber usado el operador OR. Este es verdadero si al menos una de las condiciones es verdadera. También se evalúa por circuito corto, o sea, si la primera condición es verdadera ya no se evaluará la segunda porque aunque resulte falsa la condición total OR será verdadera.

    Veamos las tablas de verdad:



    Existe también el operador booleano NOT que niega una condición, o sea, da el valor opuesto a esta. En principio uno se pregunta para que serviría algo como eso. Más adelante cuando comencemos a trabajar con las variables boolean veremos el uso de este operador. Veamos su tabla:



    -------------------------------------------------------------------------------------

    Operadores relacionales: Son los que comparan dos expresiones, tal y como hemos venido haciendo hasta ahora:



    -------------------------------------------------------------------------------------

    Un ejemplo matemático:

    Bien. Haremos un programa en el cual aplicaremos casi todo lo dado hasta ahora.
    Se nos pide realizar un programa que calcule las raíces de polinomios de segundo grado cuyos coeficientes serán ingresados por el usuario, y muestre en pantalla los mensajes correspondientes.

    Por si alguno de ustedes no está bien familiarizado con polinomios explicaré brevemente lo que es uno de segundo grado:
    Un polinomio es una función matemática con una única incógnita X la cual está elevada a distintos exponentes en los diferentes términos de la ecuación. Para que se vea mejor, un polinomio de segundo grado tiene la forma

    aX^2 + bX + c

    donde a, b y c son números reales. Por ejemplo, un polinomio podría ser 2X^2 + 4X + 2. Los números que acompañan a las X (a, b y c) son llamados coeficientes.

    Las raíces de un polinomio son aquellos valores de X que hacen que la ecuación sea nula, o sea, que valga 0.
    En el ejemplo que tenemos allí, una raíz de ese polinomio es -1. Si cambiamos la incógnita X por -1 efectivamente vemos que todo se anula:

    2*(-1)^2 + 4*(-1) + 2 = 2*1 – 4 + 2 = 2 – 4 + 2= -2 + 2 = 0.

    Dado un polinomio de segundo grado puede suceder que tenga dos raíces diferentes, una única raíz (llamada raíz doble) o que no tenga raíz. Para hallar las raíces de un polinomio aX^2 + bX + c se usa la conocida fórmula de Bascaras:



    El término bajo la raíz cuadrada (b^2-4*a*c) es llamado discriminante ya que de él depende si el polinomio tiene dos raíces, una sola o no tiene. Si el discriminante es mayor que 0 efectivamente tendremos dos raíces distintas ya que por la forma de la fórmula tenemos un ± que divide la fórmula en dos partes, por un lado resolvemos la ecuación con el signo de + luego de –b, y después resolvemos la fórmula con el signo de luego del –b:



    Esto dará dos resultados diferentes, cada uno correspondiendo a una raíz.
    Si el discriminante es nulo, o sea igual a 0, la raíz cuadrada de 0 es igual a 0, por tanto sería estúpido separar en dos la ecuación ya que hacer –b+0 o –b-0 da exactamente igual, por lo cual el resultado será único. En este caso tenemos una única raíz doble.

    Si el discriminante es menor que 0 no podremos hallar su raíz cuadrada ya que no existe raíz de un número negativo. En este caso la fórmula no puede resolverse y decimos que no existen raíces reales. En este caso pueden hallarse raíces complejas, pero eso no lo haremos ahora ya que tiene sentido solo para aquellos que se lleven bien con las matemáticas.

    Muy bien, teniendo cierto conocimiento sobre el problema comencemos a plantearnos como lo resolveremos para programarlo. El usuario ingresará en la entrada estándar los coeficientes a, b y c de nuestro polinomio. Teniendo esos valores primero debemos verificar que el valor a sea distinto de 0 ya que de ser así no estaríamos enfrentándonos a un polinomio de segundo grado sino a uno de grado uno o cero. Además, por la forma de la fórmula de Bascaras, si a vale 0 entonces 2*a también, y esté término es el divisor; al no poder dividir por 0 estaríamos enfrentándonos aun problema.

    Luego deberemos evaluar el discriminante y según lo que este dé cómo resultado tomaremos tres caminos distintos para mostrar los resultados al usuario.

    He aquí el código:

    Código:
    1 PROGRAM polinomio;
    2
    3  Var
    4     a, b, c: real; //Los coeficientes del polinomio.
    5     discriminante: real; //El discriminante.
    6     raiz1, raiz2: real; //Las raíces del polinomio.
    7
    8  BEGIN
    9      //Pedimos al usuario el ingreso de datos y leemos los mismos.
    10    write('Ingrese los coeficientes separados por espacio: ');
    11    readln(a,b,c);
    12
    13    //Verificamos que el coeficiente a sea no nulo.
    14    If a=0 then
    15       writeln('Usted no ha ingresado un polinomio de segundo grado.')
    16    else
    17    begin
    18       //Calculamos el discriminante.
    19       discriminante:= sqr(b)-4*a*c;
    20
    21       //Tomaremos los tres caminos según el valor discriminante.
    22       If discriminante=0 then
    23       begin
    24          //El polinomio tiene una única raíz.
    25          raiz1:= -b/(2*a);
    26          writeln('El polinomio tiene una raíz doble: ',raiz1:2:2);
    27       end
    28       else
    29          If discriminante>0 then
    30          begin
    31         //El polinomio tiene dos raíces.
    32         raiz1:=(-b+sqrt(discriminante))/(2*a);
    33         raiz2:=(-b-sqrt(discriminante))/(2*a);
    34
    35         writeln('El polinomio tiene dos raíces reales: ',raiz1:2:2,' y ',raiz2:2:2);
    36       end
    37       else
    38          writeln('No existen raíces reales.');
    39    end; //Fin de la instrucción ELSE del IF principal.
    40 END.
    Muy bien, como primera cosa les diré que a pesar de la explicación que yo pueda dar aquí será conveniente que ustedes mismos estudien este programa para comprenderlo bien. No es para nada complicado pero puede resultar confuso gracias a las anidaciones que se han hecho de las funciones IF…THEN…ELSE.

    En las líneas 4, 5 y 6 declaramos todas las variables necesarias para que nuestro programa funcione correctamente. En la línea número 11 leemos los tres coeficientes a la vez. Luego tenemos un IF…THEN…ELSE principal que, si el coeficiente a es igual a 0 mostrará un mensaje de error al usuario y solo en caso contrario pasará a realizar todas las demás tareas en su instrucción ELSE, la cual es un enorme bloque de instrucciones encerradas entre begin y end. En ese caso calculamos primero el discriminante ya que de él dependerán los caminos a tomar. Observar que al hacerlo (en la línea 19) usamos la función sqr que calcula el cuadrado de un número. En vez de eso podríamos haber puesto b*b que es lo mismo.

    Si el discriminante es igual a 0 mostraremos al usuario la raíz doble, sino, si el discriminante es mayor que 0 calculamos y mostramos ambas raíces, y en caso contrario le diremos al usuario que no existen raíces reales.
    Es importante que entiendan el uso de los begin y end en este programa. Recuerden que estos delimitan bloques de programa los cuales son vistos como una única instrucción. Si escribiera el código anterior a partir del primer IF de modo que en cada sentencia tuviéramos una única instrucción quedaría así:
    Código:
    If condicion1 then
       Instruccion1
    Else
    Begin
       //Aquí debería estar el cálculo del discriminante.
       If condicion2 then
          Instruccion2
       Else
          If condicion3 then
             Instruccion3
          Else
             Instruccion4;
    End;
    Esto, si tomáramos todo lo que está entre el BEGIN y el END que vemos allí como una única instrucción quedaría simplemente como
    Código:
    If condicion1 then
       Instruccion1
    Else
       Instruccion2;
    donde la Instruccion2 sería todo el enorme bloque entre el BEGIN y END.

    -------------------------------------------------------------------------------------

    Instrucción de selección CASE…ELSE:

    La instrucción CASE que veremos a continuación podría considerarse como la forma correcta de escribir una enorme cantidad de IF anidados. Veamos primero un ejemplo anidando IF en el cual el programa despliega al usuario varias opciones y dependiendo de lo que éste seleccione será lo que hará:

    Código:
    1  PROGRAM menu;
    2
    3 Var
    4    opcion: char;
    5    numero: integer;
    6
    7 BEGIN
    8     writeln('1--> Muestra un mensaje en pantalla');
    9     writeln('2--> Ingresar un número');
    10    writeln('3--> Ingresar un caracter');
    11
    12    write('Ingrese una opcion y presione ENTER: ');
    13    readln(opcion);
    14
    15    writeln;
    16
    17    If opcion='1' then
    18       writeln('MENSAJE DESPLEGADO')
    19    else
    20       if opcion='2' then
    21       begin
    22          write('Ingrese un número entero: ');
    23          readln(numero);
    24          writeln('Ha ingresado ',numero,'.');
    25       end
    26       else
    27          if opcion='3' then
    29          begin
    30             write('Ingrese un caracter: ');
    31             readln(opcion);
    32             writeln('Ha ingresado ',opcion);
    33          end
    34          else
    35             writeln('ERROR. No existe la opción ',opcion);
    36 END.
    En este ejemplo volvemos a trabajar con una variable del tipo char, o sea que contendrá caracteres, no una cadena como el tipo string sino uno solo. Esto es por un simple motivo. Al ser del tipo char cualquier símbolo que ingresemos será leído sin problemas. Nosotros mostramos las opciones del menú con números, entonces uno podría decir que para leer la opción que el usuario ingrese podríamos haber declarado una variable integer o real, sin embargo de hacerlo así, si el usuario en vez de ingresar un número ingresa una letra el programa dará un error en tiempo de ejecución al intentar almacenar una letra en una variable numérica y se cerrará. Sin embargo, al ser del tipo char, si el usuario ingresa una letra esta se leerá sin problemas y podremos desplegar al usuario un mensaje de error que indique que ha seleccionado una opción incorrecta, y de ser posible pedirle que lo intente de nuevo.

    Notar como en las condiciones de los IF comparamos el carácter leído en la variable opcion con un carácter escribiendo este explísitamente entre comillas simples. Es importante saber que si el usuario ingresa un 1 en su entrada, nosotros leeremos el carácter 1 y NO el número 1. El carácter 1 es como una letra o un símbolo, no es un número que se puede sumar o restar, es un símbolo (ya lo dije antes). Del mismo modo que uno no puede sumar letras, a+b por ejemplo, no se pueden sumar caracteres numéricos. No es lo mismo 1 que ‘1’. El primero es un número y el otro un carácter. ‘1’+’2’ equivale a la cadena ‘12’, y 1+2 es igual a 3. Esta diferencia resulta esencial, es importante que lo comprendan.

    No he puesto comentarios en este programa apropósito para que ustedes lo lean y entiendan por sí solos.
    Básicamente decimos, si el usuario ingresa el 1 muestra un mensaje, sino, si el usuario ingresa el 2 pide que ingrese un numero y muéstraselo, sino, si el usuario ingresa el 3 pídele que ingrese un carácter y muéstraselo, sino dile que lo que ha ingresado no es una opción correcta.

    Ahora veamos el mismo programa usando la instrucción CASE:

    Código:
    1 PROGRAM menu;
    2
    3 Var
    4     opcion: char;
    5     numero: integer;
    6
    7 BEGIN
    8  writeln('1--> Muestra un mensaje en pantalla');
    9  writeln('2--> Ingresar un número');
    10 writeln('3--> Ingresar un caracter');
    11
    12 write('Ingrese una opcion y presione ENTER: ');
    13 readln(opcion);
    14
    15 writeln;
    16
    17 Case opcion of
    18 '1': writeln('MENSAJE DESPLEGADO');
    19 '2': begin
    20         write('Ingrese un número entero: ');
    21         readln(numero);
    22         writeln('Ha ingresado ',numero,'.');
    23      end;
    24 '3': begin
    25         write('Ingrese un caracter: ');
    26         readln(opcion);
    27         writeln('Ha ingresado ',opcion);
    28      end;
    29 else
    30     writeln('ERROR. No existe la opción ',opcion);
    31 end; //De la instrucción CASE.
    32 END.
    Hasta la línea 16 nuestros ejemplos son exactamente iguales. Ahora, en la línea 17 en vez de tener un IF tenemos la declaración de la instrucción CASE. Su sintaxis es la siguiente:

    Código:
    Case variable of
    Etiqueta1: instruccion1;
    Etiqueta2: instruccion2;
    ...
    EtiquetaN: instrucciónN;
    Else
       Intruccion_por_defecto;
    End;
    Esta instrucción se fijará en el valor de la variable colocada entre la palabra CASE y la palabra OF, en nuestro ejemplo se trata de la variable opcion. Luego tomará el camino en el cual el valor de la variable sea igual al de la etiqueta. El ELSE al final indica lo que se debe hacer si la variable no corresponde con ninguna de las etiquetas anteriores. Este ELSE puede ir o no, es opcional. Si no está no se ejecutará nada y se continuará con lo que haya debajo en el código, pero no habrá error. En este caso hemos usado el ELSE par decir al usuario que no ingresó nada de lo esperado. Notar que antes de este ELSE sí debe ir un punto y coma que cierre la instrucción anterior, no como en el caso de los ELSE que se usan en una instrucción IF.

    Siempre al final de la instrucción CASE debe ir un END que finalice en punto y coma para indicar el final de esta instrucción. No colocarlo es un error de sintaxis.

    Notar que las instrucciones para cada etiqueta pueden ser bloques de instrucciones delimitados por sus respectivos BEGIN y END.
    Es importante saber que las etiquetas representan los valores que debe tomar la variable del encabezado del CASE para que el programa tome tal o cual camino. Es posible indicar más de un valor a la vez en una misma etiqueta, simplemente separando cada valor por una coma:

    Código:
    Case variable of
    Valor1, valor2: instruccion1;
    Valor3, valor4, valor5: instruccion2;
    . . .
    ValorI, valorN: instruccionJ;
    End;
    IMPORTANTE: La variable del encabezado del CASE debe ser de un tipo ORDINAL, o sea integer, char, enumerado, boolean o subrango.

    -------------------------------------------------------------------------------------

    Ejercicio: Este es un simple ejercicio para que usen CASE. Quiero que en un solo programa junten los siguientes ejemplos que vimos hasta ahora: el programa HolaMundo, el del Área de un Triángulo, el que dividía dos cifras habiéndolo modificado para que muestre un error si se ingresa la segunda cifra igual a 0, y el programa que desglosaba un número de cuatro cifras modificado para que muestre un error si el usuario ingresa un número inválido, o sea, uno que sea menor a 1000 o mayor a 9999. Su programa debe mostrar un menú como el siguiente:

    1) Hola Mundo
    2) Calcular el Área de un Triángulo
    3) Dividir dos números reales
    4) Sumar los dígitos de un número de cuatro cifras

    Selección:


    Cuando el usuario elija una opción su programa habrá de realizar las tareas pertinentes y en caso contrario notificar el error. No continúen hasta no lograr hacer esto.

    ------------------------------------------------------------------------------------

    Además ingresen en ESTE ENLACE para realizar todos los ejercicios allí propuestos, los cuales tratan todo lo dado específicamente en esta lección.


    Espero que todo haya sido claro. Esperaré sus comentarios y sus dudas.
  1. ¿Este tema te pareció interesante? Compártelo!

    ¿No es lo que buscabas? Intenta buscar un tema similar

    16 comentarios / 1291 Visitas

      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    03/01/2012
    #2 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    Parece que lo haga aposta el tener una duda en cada lección, pero no es asi jaja
    A mi, el codigo de saber si un caracter es mayor o igual, o menor o igual que otro
    siempre me aparece el que la primera letra es mayor o igual a la segunda.

    Hay algun error?? porque yo no lo encuentro

    Gracias

      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    03/01/2012
    #3 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    He hecho el codigo para que se introduzca cada caracter por separado, primero uno y despues el otro, y de esta forma si que me da diferentes respuestas.

    Hay algun motivo?

      • 322
      • mensajes
      • miembro desde
      • 07/02/07
    04/01/2012
    #4 Re: Programando desde 0: 06- Condiciones booleanas y selección.
    Cita Escrito por raulexploit Ver mensaje
    He hecho el codigo para que se introduzca cada caracter por separado, primero uno y despues el otro, y de esta forma si que me da diferentes respuestas.

    Hay algun motivo?
    Si puedes publícame tu código fuente así puedo ver donde está el problema.

    Gracias por publicar tus dudas.

    Saludos.
      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    04/01/2012
    #5 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    PROGRAM Condiciones;

    VAR
    a, b: char;

    BEGIN
    write('Introduzca un caracter: ');
    readln(a);
    write('Introduzca otro caracter: ');
    readln(b);

    If a>b then write('El primero es mayor que el segundo');
    If b END.


    Con este codigo que te acabo de poner si que me funcionan los condicionales, pero con el que pusiste tu (a continuacion te lo cito) siempre me da la primera respuesta

    Código:
    PROGRAM Caracteres;

    VAR
    letra1, letra2: char; //Una variable para cada letra.

    BEGIN
    Write('Ingrese dos letras separadas por espacios: ');
    Readln(letra1,letra2); //Leemos la entrada y la asignamos a las variables.
    Writeln; //Dejamos una línea en blanco.

    If letra1<=letra2 then 12 writeln('La primera letra es menor o igual a la segunda');

    If letra1>=letra2 then 15 writeln('La primera letra es mayor o igual a la segunda');

    Readln;
    END.
    y no se el por que.
      • 322
      • mensajes
      • miembro desde
      • 07/02/07
    04/01/2012
    #6 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    Pues el error es mío y está en pedir que las letras se escriban separadas por espacios. Esto hace que la primera variable tome el caracter de la primera letra escrita y la segunda variable toma el caracter espacio como valor. De este modo la segunda letra nunca es leída.

    Comparando cualquier letra con el caracter de espacio resulta que este siempre es menor. Por eso el resultado siempre da igual.

    Las letras deben ingresarse sin estar separadas por espacios.

    Saludos, y gracias por tu observación.

      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    06/01/2012
    #7 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    Hola otra vez jaja espero no darte mucho trabajo

    Estoy intentando realizar el ejercicio numero 12
    pero la unica manera que se me ocurre de hacerlo
    es utilizando un bucle, pero hasta ahora no has hecho mencion de ello

    Por eso nose si hay otra forma de realizar el ejercicio o me reservo
    el ejercicio para cuando vea el tema de los bucles.

    Saludos y gracias

    EDITO:

    y si me puedes dar una pista para el 13 te lo agradeceria... la pista es en relacion de como hago que detecte el valor de "d" y le ponga el signo "+" debajo.
    Una pista, no quiero la solución

    gracias

      • 322
      • mensajes
      • miembro desde
      • 07/02/07
    06/01/2012
    #8 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    Sobre el ejercicio 12 te paso una solución que le di una vez a otra persona que me preguntó cómo resolverlo:

    Este ejercicio no es complejo, pero cuesta entenderlo.
    El precio de una carta que pesa hasta 1 onza es de $0.22. O sea que si en la entrada estándar nos ponen un peso menor o igual a 1 el precio del envío es justamente $0.22.
    Ahora bien, pasada la onza, se agrega $0.17 por cada onza de más o fracción de onza. ¿Qué significa eso?

    Que si la carta pesa 2 onzas entonces vale 0.22 + 0.17 porque hay 1 onza más. Si la carta pesa 3 onzas entonces vale 0.22 + 0.17 + 0.17 porque hay 2 onzas más de lo permitido.
    Se pesara 4 onzas, entonces valee 0.22 + 0.17 + 0.17 + 0.17 porque hay tres onzas más. ¿Se entiende?

    La fracción es, si además hay algo después de la coma, o sea:
    Si una carta pesa 1.01 onza, entonces se cobra 0.22 + 0.17 porque existe un 0.01 de fracción, o sea, pesa más de 1 onza.

    Si la carta pesa 2.04 onzas, entonces el precio es 0.22 + 0.17 + 0.17. O sea, un recargo por la onza de más y otro por la fracción de 0.04 ya que la carta pesa más de 2 onzas, entonces se calcula como si pesara 3 ¿se entiende?.

    Si el peso no es exacto, o sea, si no es por ejemplo 3.00, entonces se calcula además un recargo de 0.17, como si hubiera otra onza más.
    Tómenlo como si redondeáramos siempre hacia arriba:
    Un peso de 1.01 es 2.00
    1.00 es 1.00
    2.09 es 3.00
    2.01 es 3.00
    3.02 es 4.00
    3.00 es 3.00

    ¿Si?

    Si han logrado entender lo que se pide, entonces les dejo el código que hice como solución:

    Código:
    PROGRAM Leccion6Ejercicio12; 
     
    CONST 
        VALOR_MIN= 0.22; //El valor mínimo de una carta. 
        VALOR_ADIC= 0.17; //El valor adicional por onza o fracción de onza. 
     
    VAR 
        peso: REAL; //El peso que leeremos desde la entrada estándar. 
        costo: REAL; //El costo que calcularemos según el peso leído. 
        adicional: REAL; //Para calcular el valor adicional de la carta. 
     
    BEGIN 
        Write('Ingresa el peso de la carta: '); 
        ReadLn(peso); 
        WriteLn; 
     
        adicional:= 0; //En principio no tenemos valor adicional. 
     
        (*El siguiente IF calcula el valor adicional solo si el peso>1*) 
        IF peso>1 THEN 
        Begin 
        (*El valor adicional es $0.17 por onza adicional o fracción. 
        Entonces calculo primero el valor adicional por onza adicional*) 
          adicional:= adicional + VALOR_ADIC*(trunc(peso)-1); 
     
        (*Además de sumar $0.17 por cada onza debo ver si existe fracción de peso, 
        o sea, no era un peso exacto (ej: 1.00, 3.00). Entonces si existe fracción 
        agrgo al valor adicional ya calculado otros 0.17*) 
          IF (peso-trunc(peso)>0) THEN 
              adicional:= adicional + VALOR_ADIC; 
        End; 
     
        (*El costo del envío es es valor mínimo (0.22) más el recago adicional calculado*) 
        costo:= VALOR_MIN + adicional; 
     
        (*Mostramos los resultados en pantalla*) 
        WriteLn('Peso    ','Costo'); 
        WriteLn(peso:2:2,'   $',costo:2:2); 
        ReadLn; 
    END.
    Sobre el ejercicio 13 te mostraré también la explicación dada a varios lectores pero no te daré el código fuente a ver si te ayuda:

    Descripción de lo que haré:

    Para resolver este ejercicio, ya que leemos el entero de 4 dígitos, será primero desglosarlo en sus cuatro dígitos (esto ya deberían saber hacerlo) para así tener todas sus cifras por separado.
    Luego compararé de izquierda a derecha esas cifras con el entero de una cifra, si la cifra coincide con el entero escribo un signo de +, sino escribo un espacio.

    Ejemplo: Sea el entero 1234 y el entero 3. Comparo primero el 1 con el 3, como no coinciden escribo un espacio. Luego comparo el 2 con el 3, tampoco coinciden, escribo otro espacio. Ahora el 3 con el 3, sí coinciden, entonces escribo un +. Ahora el 4 con el 3, no coinciden escribo un espacio.

    A su vez tendré un booleano que se hará TRUE si en algún momento existe alguna coincidencia, en caso contrario será siempre FALSE. Esto me ayudará para mostrar el mensaje final al usuario.

    Otra forma de hacerlo podría ser, en vez de usar un booleano, contar la cantidad de espacios escritos, si esta es igual a 4 significa que nunca hubo coincidencia y pues, mostramos el mensaje correspondiente.

    Les mostraré la forma con booleano, les dejo a ustedes la otra. Claro está que hay más y que si a ustedes se les ocurren otras tanto mejor.



    SALUDOOOOOOOOOOOOOOS
      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    06/01/2012
    #9 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    ufff las mates nunca fueron mi punto fuerte jaja
    pero entendi todo el codigo del ejercicio 12

    sobre el ejercicio 13 con la mitad de la explicacion ya lo realice
    gracias

    voy a ver que tal se me dan los dos ultimos y asi pasar a la siguiente leccion

      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    07/01/2012
    #10 Re: Programando desde 0: 06- Condiciones booleanas y selección.

    Ultima duda de la lección.
    En el ejercicio 14 piden numeros complejos... (ya dige que las mates no eran mi fuerte)
    pero aun asi se que un numero compleja esta formado por
    a + bi donde i=sqrt(-1)
    por lo tanto:
    a, b: real;
    signo: char;
    i: ¿¿¿¿¿¿¿como indico que es imaginario??????

    pero aqui me quedo ... nose como indicar al resultado si es complejo o no

    Gracias una vez mas
    tranquilo ya termino la leccion jajaja

12 Último