jueves, 19 de abril de 2012

Estucturas de Control en C: Los Condicionales if y else

C es un lenguaje de programación estructurado. Esto quiere decir que en sus programas el orden en el cual se ejecutan las instrucciones es, por defecto, el orden en el que aparecen. En los programas que hemos visto hasta ahora así ha sido. Esto puede parecer obvio de entrada, pero no lo es. Algunos lenguajes de programación no son estructurados, lo cual dificulta la lectura del código y su mantenimiento; además los programas de esos lenguajes son más susceptibles de contener errores difíciles de detectar. No obstante lo anterior, una de las principales tareas de un programa de computadora es la toma de decisiones. Imagine que escribe una aplicación para evaluar el desempeño de sus alumnos de programación. Las opciones son solamente dos: Aprobado o Reprobado. Para esto tiene una lista de las calificaciones de los exámenes finales. Para cada uno de sus alumnos tendrá que recibir la calificación y tomar una decisión: si es mayor a 6, imprime 'Aprobado', de lo contrario imprime 'Reprobado'. El código deberá contener las instrucciones que hay que llevar a cabo si la el alumno obtuvo más de 6 y también deberá contener las instrucciones para el caso en el que reprueba. Alguno de ese grupo de instrucciones estará primero que el otro en el orden de aparición. Sin embargo, sólo debe realizarse uno. La instrucción if hace que el programa no realice cierto grupo de instrucciones y transfiere el control justo a las instrucciones siguientes. Para delimitar exactamente qué instrucciones se evitarán, el cuerpo de if se limita generalmente con unas llaves {}. Esto quedará más claro con el siguiente programa: Copie, pegue, compile y ejecute:


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++
   *                                                      *
   *  ESTE PROGRAMA RECIBE TRES NUMEROS ENTEROS Y DECIDE  *
   *  EN CADA CASO SI:                                    *
   *  EL NUMERO ES POSITIVO                               *              
   *  EL NUMERO ES POSITIVO O NEGATIVO                    *
   *  EL NUMERO ES POSITIVO, NEGATIVO O CERO              *
   *                                                      *
   *  LO QUE RECIBE:                                      *
   *  TRES NUMEROS ENTEROS                                *
   *                                                      *
   *  LO QUE HACE:                                        *
   *  IMPRIME EN CADA CASO SI EL NUMERO ES:               *
   *  POSITIVO                                            *
   *  POSITIVO O NEGATIVO                                 *
   *  POSITIVO, NEGATIVO O CERO                           * 
   *++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

  /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   *                                                                    *
   *                              ALGORITMO:                            *
   *  Pedir un numero al usuario                                        *
   *  Recibir el numero                                                 *
   *    Si el numero recibido es mayor que 0                            *
   *    Imprimir "El numero es positivo                                 *
   *                                                                    *
   *  Pedir un numero al usuario                                        *
   *  Recibir el numero                                                 *
   *                                                                    *
   *    Si el numero recibido es mayor que 0                            *
   *         Imprimir "El numero es positivo                            *
   *    De lo contrario                                                 *
   *         Imprimir "El numero no es positivo                         *
   *                                                                    *
   *                                                                    *
   *  Pedir un numero al usuario                                        *
   *  Recibir el numero                                                 *
   *                                                                    *
   *    Si el numero recibido es mayor que 0                            *
   *         Imprimir "El numero es positivo                            *
   *    De lo contrario                                                 *
   *         Si el numero es menor que 0                                *
   *            Imprimir "El numero es negativo                         *
   *         De lo contrario                                            *
   *            Imprimir "El numero es 0"                               *
   *                                                                    *
   **********************************************************************/

 #include <stdio.h>
 
 int main()
 {  /* Abre main */
 int numero;
 printf("\nPor favor introduzca un numero entero: ");
 scanf("%d", &numero);

 if ( 0 < numero )
 /* Es una buena practica de programacion hacer las comparaciones de esta forma*/
 printf("\nEl numero que introdujo es positivo\n ");

 printf("\nPor favor introduzca de nuevo un numero entero: ");
 scanf("%d", &numero);
 
 if ( 0 < numero )
 printf("\nEl numero que introdujo es positivo\n ");
 else
 printf("\nEl numero que introdujo no es positivo\n ");

 printf("\nPor favor introduzca de nuevo un numero entero: ");
 scanf("%d", &numero);
  
 if ( 0 < numero )
 printf("\nEl numero que introdujo es positivo\n ");
 else
 if ( 0 > numero )
 printf("\nEl numero que introdujo es negativo\n ");
 else
 printf("\nEl numero que introdujo es 0\n");
 
 printf("\nHasta pronto!\n");
 
 return 0;
 }  /* Cierra main */


Ahora hagamos un análisis del programa línea por línea para revisar cada instrucción.



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++
   *                                                      *
   *  ESTE PROGRAMA RECIBE TRES NUMEROS ENTEROS Y DECIDE  *
   *  EN CADA CASO SI:                                    *
   *  EL NUMERO ES POSITIVO                               *              
   *  EL NUMERO ES POSITIVO O NEGATIVO                    *
   *  EL NUMERO ES POSITIVO, NEGATIVO O CERO              *
   *                                                      *
   *  LO QUE RECIBE:                                      *
   *  TRES NUMEROS ENTEROS                                *
   *                                                      *
   *  LO QUE HACE:                                        *
   *  IMPRIME EN CADA CASO SI EL NUMERO ES:               *
   *  POSITIVO                                            *
   *  POSITIVO O NEGATIVO                                 *
   *  POSITIVO, NEGATIVO O CERO                           * 
   *++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

Estas líneas, encerradas por los caracteres /* */ son un comentario. Los comentarios ayudan a documentar el programa. No está de más remarcar la importancia de esto. Con una simple mirada a este recuadro usted, o cualquier lector del código, sabe de manera general qué hace el programa. Se incluye lo que se pide del usuario lo que el programa hace. Estas líneas son prescindibles para el programa, pero no lo son tanto para el programador. Sin embargo no es necesario incluirlas.

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   *                                                                    *
   *                              ALGORITMO:                            *
   *  Pedir un numero al usuario                                        *
   *  Recibir el numero                                                 *
   *    Si el numero recibido es mayor que 0                            *
   *    Imprimir "El numero es positivo                                 *
   *                                                                    *
   *  Pedir un numero al usuario                                        *
   *  Recibir el numero                                                 *
   *                                                                    *
   *    Si el numero recibido es mayor que 0                            *
   *         Imprimir "El numero es positivo                            *
   *    De lo contrario                                                 *
   *         Imprimir "El numero no es positivo                         *
   *                                                                    *
   *                                                                    *
   *  Pedir un numero al usuario                                        *
   *  Recibir el numero                                                 *
   *                                                                    *
   *    Si el numero recibido es mayor que 0                            *
   *         Imprimir "El numero es positivo                            *
   *    De lo contrario                                                 *
   *         Si el numero es menor que 0                                *
   *            Imprimir "El numero es negativo                         *
   *         De lo contrario                                            *
   *            Imprimir "El numero es 0"                               *
   *                                                                    *
   **********************************************************************/

Este recuadro también es un comentario. De hecho se trata del algoritmo en seudocódigo del programa. Explica paso a paso qué hace el programa. Si usted quiere, puede convertir este seudocódigo a un programa en cualquier lenguaje, ya que no está limitado por particularidades del lenguaje C. También es prescindible y podría no estar. Sin embargo, es muy importante para que el lector sepa exactamente de qué va el algoritmo y pueda apreciar sus virtudes y sus defectos. De otra forma se deja al lector la tarea de leer y entender el programa leyéndolo en C, lo cual no es conveniente. C está pensado para ser leído por una máquina, no por un humano. El científico de la computación Donald Knuth escribió esta frase que, sacada un poco de contexto se puede aplicar aquí: "tenemos que cambiar la tradicional actitud ante la construcción de software. En vez de pensar que nuestra principal tarea es indicar a una computadora qué hacer, concentrémonos en explicar a las personas lo que queremos que la computadora haga".

#include <stdio.h>

Esta línea indica que usaremos la entrada y salida estándar con las funciones printf y scanf.

int main()
 {  /* Abre main */

La primera línea declara el tipo de datos que regresa main y además indica que no recibe ningún dato.
El cuerpo de main está limitado por llaves. { indica el inicio del cuerpo de main, tal como lo indica el comentario

int numero;

Antes de recibir una variable (un número, un carácter, una cadena) de parte del usuario es necesario declarar la existencia de dicha variable. Esto reserva memoria para guardarla. Es necesario especificar el tipo de datos que vamos a recibir. En este caso se trata de un entero (int).

printf("\nPor favor introduzca un numero entero: ");

La función printf sirve para imprimir o enviar datos como salida. En este caso lo que se envía es el mensaje "Por favor introduzca un numero entero".

scanf("%d", &numero);

La función scanf recibe un entero ( indicado por los caracteres %d) y lo asigna a la variable numero.

if ( 0 < numero )

La instrucción if es un condicional. Su significado es el mismo que en inglés (si). if requiere de una condición lógica que pueda evaluarse como 'falso' o 'verdadero'. Esa condición lógica debe ir encerrada entre paréntesis ().
Dentro de los paréntesis también hay algo nuevo. El operador de relación < cuyo significado es el mismo que en aritmética: menor que. Así que el cuerpo de if se realiza sólo si la condición encerrada entre paréntesis es verdadera. En este caso sólo si 0 es menor que la variable número. El cuerpo de if es, por defecto, la sentencia justo después del enunciado if(condición). Si queremos que se realice más de una instrucción, debemos encerrar ese bloque con llaves {}:
if ( condición )
{
Instrucción 1
Instrucción 2
....
....
Instrucción n
}

Los operadores relacionales están presentados abajo en la siguiente tabla:

Operadores de relación:

 >                    Mayor que
 <                    Menor que 
 ==                   Igual
 >=                   Mayor o Igual que
 <=                   Menor o Igual que

Los operadores mayor que > y menor que < son los mismos que en aritmética y por lo tanto son ya familiares. El operador de igualdad sí es distinto. Anteriormente hemos visto el operador de asignación = que toma el valor de la derecha y lo asigna a la variable de la izquierda. Doble igual == no realiza una asignación sino una COMPARACIÓN. Algunos problemas pueden surgir sí se confunden estos operadores (y es algo que pasa con mucha frecuencia), así que hay que tener cuidado para no confundirlos. Mayor o igual >= y menor o igual <= son también un poco distintos a los símbolos aritméticos, pero es relativamente fácil recordarlos.

/* Es una buena practica de programacion hacer las comparaciones de esta forma*/

Esta línea hace referencia a la forma en que colocamos la condición dentro de los paréntesis de if. Hay dos maneras de escribir la condición 'número es mayor que o'. La primera es esta:

if ( numero > 0 )

Que lo expresa directamente, 'número es mayor que 0', en tanto que la segunda es esta:

if ( 0 < numero )

Que lo expresa al revés, '0 es menor que número'.
Cualquiera de las dos formas es correcta. Sin embargo, suponga que la condición es 'numero es igual a tres'. En este caso escrita en lenguaje C la condición sería:

if ( numero == 3 )

La instrucción es totalmente correcta. Sin embargo, es un error muy común, que el programador omita un = en ==, escribiendo una instrucción ligeramente distinta:

if ( numero = 3 )

Ese problema no es reportado por el compilador, porque no es un error de sintaxis, es un error de lógica. En la práctica también resulta un error muy difícil de detectar a través de leer el código. Lo que ocurre, es que en lugar de una comparación se realiza una asignación. El valor de la derecha (3 en este caso) se asigna a la variable de la izquierda (numero) y después se evalúa la condición. Sin embargo, el condicional if sólo puede tener 2 valores: 'verdadero' (1) o 'falso' (0). El compilador de C considera verdadero todo lo que no sea falso. Así que en este caso, como el valor de la condición es 3 (el valor de la variable una vez realizada la asignación). Lo que está haciendo el programador es cambiar el valor de la variable, en tanto que el compilador toma la condición como 'verdadera' y el cuerpo del if se ejecuta siempre. Tan común es este problema que Niklaus Wirth, creador del lenguaje de programación Pascal (lenguaje pensado para estudiantes), para evitar que sus alumnos lo cometieran, estableció las asignaciones como:=, y las comparaciones con =, de forma que el natural = sirviera de comparación y el antinatural := obligara a pensar antes de ser usado. Todo esto se puede evitar fácilmente si se crea la buena costumbre de escribir los condicionales no como (numero = 3) sino como

if ( 3 == numero )

ya que, en caso de que se omita un = en la condición, el compilador mandará un mensaje de error, ya que las asignaciones en C se hacen de derecha a izquierda, y no de izquierda a derecha. Este consejo, con un ejemplo paso a paso, y otros consejos pueden encontrarse en esta liga: Consejos para programar. Fórmese desde ahora el hábito de escribir los condicionales de esta manera y evítese problemas en el futuro.

printf("\nEl numero que introdujo es positivo\n ");

Atención: Ésta línea sólo se imprime si la condición anterior se evalúa como 'verdadera' o 'true'. De lo contrario se omite. Esta es una forma de transferir el control del programa, en este caso a la instrucción siguiente. Si el número introducido es 0, o negativo, entonces no ocurre nada en el programa.

printf("\nPor favor introduzca de nuevo un numero entero: ");
scanf("%d", &numero);
 

Este par de líneas no contienen nada que no hayamos visto ya: se pide y se recibe un número del usuario.

if ( 0 < numero )
printf("\nEl numero que introdujo es positivo\n ");
  

Estas dos líneas son exactamente las mismas de arriba, primero evaluamos si el entero es positivo. Si esta condición (y sólo es cierta) se realiza la siguiente instrucción o conjunto de instrucciones limitadas por llaves. En este caso es sólo una instrucción simple.

else

La instrucción else indica lo que el programa hará en caso de que la condición no sea cierta. La estructura de la condición if - else es la siguiente:

if ( condición )
{
 instrucción 1
 instrucción 2
 .........   .
 .........   .
 .........   .
 instrucción n
}

else
{  
 instrucción 1
 instrucción 2
 ..........  .
 ..........  .
 ..........  .
 instrucción n
}

El programa realiza el cuerpo de instrucciones de if si la condición es verdadera, en tanto que realiza el cuerpo de instrucciones de else si la condición es falsa. else sólo aparece después de if en un programa.
En nuestro caso, si la condición de if no se cumple, es decir, si 0 > numero, entonces se realiza la siguiente instrucción:

printf("\nEl numero que introdujo no es positivo\n ");

Lo único que podemos decir del número es que no es positivo.


printf("\nPor favor introduzca de nuevo un numero entero: ");
scanf("%d", &numero);

De nuevo la misma petición al usuario y el almacenamiento del número entero en la variable numero.


if ( 0 < numero )
printf("\nEl numero que introdujo es positivo\n ");

Y de nuevo la misma acción para el caso en el que el número sea positivo.

else

De lo contrario, es decir, si el número no es positivo, entonces se ejecutan las siguientes instrucciones:

if ( 0 > numero )
printf("\nEl numero que introdujo es negativo\n ");
else
printf("\nEl numero que introdujo es 0\n");

Estas líneas son todas el bloque de instrucciones que corresponden al else anterior. Se trata de una instrucción if-else anidada dentro del else del primer if. La estructura es la siguiente:

if (condición 1)
{ 
 instrucción 1
 instrucción 2
 .............
 .............
 instrucción n
}
else
{
  if(condición 2)
  { 
  instrucción anidada 1
  instrucción anidada 2
  ........... ....... .
  ........... ....... .
  instrucción anidada n
  }
}

A menos que se usen llaves, {}, el compilador de C asigna un else con el if inmediatamente anterior. Para evitar algún tipo de confusión es conveniente usar llaves aún cuando no sea necesario.
Así pues, si el número no es negativo quedan dos opciones: o bien es cero o bien es negativo. Estas dos posibilidades se consideran en el if-else anidado. Si 0 es mayor que el número, entonces el número es negativo, y se ejecuta el cuerpo del if anidado (se imprime el mensaje "el número que introdujo es negativo"). De lo contrario, el número tiene que ser cero. En ese caso se tendrá que ejecutar la instrucción en el cuerpo de if (se imprime el mensaje "el número que introdujo es 0".)

printf("\nHasta pronto!\n");

Esta instrucción despide al usuario, indicando el final del programa.

return 0;

La instrucción return 0; indica el fin del programa. La función main puede retornar cualquier entero. Puede modificar este programa para poner 23 o 65 o cualquier entero en esta instrucción y será correcto.

}  /* Cierra main */

Se cierra el cuerpo de main y un comentario lo indica así.
_____________________________________________________________________________
Lo que aprendió:
El orden por defecto en que se realizan las instrucciones de un programa en C.
Los operadores de relación.
El uso de la instrucción if para transferir el control del programa.
El uso de la instrucción if-else como una transferencia anidada del control del programa.
______________________________________________________________________________
Esta página forma parte del Curso de C Con Programas Explicados Línea por Línea
Índice
Entrada Anterior
Entrada Siguiente

No hay comentarios:

Publicar un comentario

Related Posts Plugin for WordPress, Blogger...