if()-else
.
if() else
en C.
if()else
![]() |
if (condición) /* 1 */ { Bloque; /* 2 */ } else { Bloque; /* 3 */ } |
if() else
hace fácil comprender su actuación desde el punto de vista del flujo de control. La sentencia
if() else
posee tres partes bien diferenciadas:
expresión de control
se evalúa al llegar el control a la sentencia
if()
; su valor podrá ser nulo (falso) o no nulo (verdadero). Si el valor de la expresión de control es verdadero, se ejecutará el bloque [2]; en caso contrario, se ejecutará el bloque [3]. Las llaves son opcionales únicamente cuando el bloque en cuestión ([2] o [3]) contiene una sola sentencia. Y la cláusula
else
es
opcional
. Un primer ejemplo de uso de la sentencia
if()-else
podría ser el siguiente:
#include<stdio.h> int main(int argc, char * argv[]) { int a; int b; int condicion; /* no mire esto no mire esto no mire esto no mire esto */ if (3 == argc) { a = strtol(argv[1], NULL, 10); b = strtol(argv[2], NULL, 10); } else { /* mire esto mire esto mire esto mire esto */ a = 1; b = 2; } condicion = a < b; if (condicion) printf("Este bloque se ejecuta porque %d < %d\n", a, b); condicion = a > b; if (condicion) printf("Este bloque se ejecuta porque %d es mayor que %d\n", a, b); else printf("Pero este otro bloque se ejecuta porque %d no es mayor que %d\n", a, b); return 0; }
if()
no tiene cláusula else y sólo hace algo cuando es a < b. El segundo
if()
tiene una cláusula
else
y siempre se ejecuta uno u otro bloque. Los resultados de la ejecución de este programa son como sigue:
[cauldron:04xx_PROGS]> ./a.out Este bloque se ejecuta porque 1 < 2 Pero este otro bloque se ejecuta porque 1 no es mayor que 2 [cauldron:04xx_PROGS]> ./a.out 2 1 Este bloque se ejecuta porque 2 es mayor que 1 [cauldron:04xx_PROGS]>
if()
para decidir la posible ejecución de bloques de código. Estos bloques irán encerrados entre llaves. Un ejemplo sencillo puede ser la resolución de una ecuación de segundo grado, en que será conveniente (aunque no necesario - ¿sabrá hacerlo el lector?) emplear varias sentencias en cada bloque. Insistimos: es imprescindible emplear llaves para delimitar los bloques en la sentencia
if()
. Si no se emplean llaves por error, se tienen varios casos. Si las llaves omitidas corresponden al bloque
else
([3]), entonces el compilador no puede detectar el error; interpretará que la única sentencia del bloque [3] es la primera (exclusivamente) que aparezca inmediatamente después de
else
. Entonces la ejecución será correcta para el caso en que la sentencia de control sea falsa, porque se ejecutará el contenido (incorrecto) del bloque [3], y todas las sentencias posteriores. Sin embargo, la ejecución será incorrecta para el caso en que la sentencia de control sea verdadera, porque se ejecutará el bloque [2] y también todas las sentencias del bloque [3], a excepción de la primera. Si el bloque [3] está vacío, se prescindirá por completo de la cláusula
else
(conjunto formado por
else
y el bloque asociado).
if()-else
cuando la expresión de control es un número entero. Verificar que es posible prescindir de llaves ("{" y "}") cuando el contenido del bloque es una sola sentencia.
/* Este programa muestra la utilización de la sentencia if() else. */ #include <stdio.h> int n; int main(void) { if(1) printf("La expresión de control se evalúa en el sentido lógico.\n\n"); n = 1; if (n>0) printf("%2d es mayor que 0.\n", n); else printf("%2d no es mayor que 0.\n",n); n = -1; if (n>0) printf("%2d es mayor que 0.\n", n); else printf("%2d no es mayor que 0.\n",n); return 0; } /* RESULTADO La expresión de control se evalúa en el sentido lógico. 1 es mayor que 0. -1 no es mayor que 0.*/
a
,
b
o
c
tomen valores nulos.
/* Este programa permite resolver ecuaciones de segundo grado. Sirve como ejemplo de anidamiento de estructuras if() else. */ #include <stdio.h> #include <math.h> /* Imprescindible - contiene sqrt() */ float a, /* coeficiente de x^2 */ b, /* coeficiente de x */ c, /* término independiente */ d; /* discriminante */
float r1,r2, /* raíces reales y distintas */ preal, pimaginaria, /* Raíces complejas conjugadas */ rrd; /* Raíz real doble */ int main(void) { printf("Resolución de ecuaciones de segundo grado, ax^2 + bx + c = 0.\n\n"); printf("Escriba los coeficientes a, b y c separados por espacios: "); scanf("%f %f %f", &a, &b, &c); printf("\nLa ecuación es %fx^2",a); b > 0.0 ? printf(" +") : printf(" "); printf("%fx",b); c > 0.0 ? printf(" +") : printf(" "); printf("%f = 0.", a, b, c); printf("\n\nSolución"); d = b*b - 4.0*a*c; if (d > 0.0) /* discriminante positivo, raíces reales y distintas */ { r1 = (-b + sqrt(d))/(2.0*a); r2 = (-b - sqrt(d))/(2.0*a); printf("\n\nRaíces reales y distintas: r1 = %f, r2 = %f", r1, r2); } else { if (d < 0.0) /* discriminante negativo, raíces complejas conjugadas */ { preal = (-b)/(2.0*a); pimaginaria = sqrt(-d)/(2.0*a); printf( "\n\nRaíces complejas conjugadas: %f+j%f, %f-j%f", preal, pimaginaria, preal, pimaginaria); } else { rrd = (-b)/(2.0*a); printf("\n\nUna raíz real doble: rrd = %f", rrd); } } puts("\n\nTerminación normal del programa.\n"); return 0; } /* COMENTARIOS Obsérvese que no se han estudiado todos los valores posibles de a, b y c. Si alguno o todos son ceros, se producen casos especiales que no se han tratado. Este programa es correcto, pero NO es robusto. */Modificación .- Construir una nueva versión del programa anterior, adaptándolo de tal modo que admita sus parámetros a través de la línea de órdenes
#include <stdio.h> #include <stdlib.h> /* Imprescindible para utilizar strtof */ #include <math.h> /* Imprescindible - contiene sqrt() */ float a, /* coeficiente de x^2 */ b, /* coeficiente de x */ c, /* término independiente */ d; /* discriminante */ float r1,r2, /* raíces reales y distintas */ preal, pimaginaria, /* Raíces complejas conjugadas */ rrd; /* Raíz real doble */ int main(int argc, char * argv[]) { printf("Resolución de ecuaciones de segundo grado, ax^2 + bx + c = 0.\n\n"); if (4 != argc) { printf("\n\nUtilización: ./resuelve a b c\n\n"); return 0; } a = strtof(argv[1], NULL); b = strtof(argv[2], NULL); c = strtof(argv[3], NULL); printf("\nLa ecuación es %fx^2",a); b > 0.0 ? printf(" +") : printf(" "); printf("%fx",b); c > 0.0 ? printf(" +") : printf(" "); printf("%f = 0.", a, b, c); printf("\n\nSolución"); d = b*b -4.0*a*c; if (d > 0.0) /* discriminante positivo, raíces reales y distintas */ { r1 = (-b + sqrt(d))/(2.0*a); r2 = (-b - sqrt(d))/(2.0*a); printf("\n\nRaíces reales y distintas: r1 = %f, r2 = %f", r1, r2); } else { if (d < 0.0) /* discriminante negativo, raíces complejas conjugadas */ { preal = (-b)/(2.0*a); pimaginaria = sqrt(-d)/(2.0*a); printf( "\n\nRaíces complejas conjugadas: %f+j%f, %f-j%f", preal, pimaginaria, preal, pimaginaria); } else { rrd = (-b)/(2.0*a); printf("\n\nUna raíz real doble: rrd = %f", rrd); } } puts("\n\nTerminación normal del programa.\n"); return 0; }Comentarios .- Este programa muestra la forma de insertar parámetros a través de la línea de órdenes. A diferencia del anterior, la función
main()
admite los parámetros
argc
y
argv
, a través de los cuales se pasa información desde el sistema operativo hasta el programa. En el caso que nos ocupa, es preciso pasar al programa tres números reales, que corresponderán a los argumentos
argv[1]
,
argv[2]
y
argv[3]
respectivamente (el nombre del programa corresponde a
argv[0]
). Estos valores deben traducirse después al formato binario, lo cual se hace mediante llamadas a la función
strtol
.
srandom()
para generar un número aleatorio comprendido entre los dos que marcan los extremos del intervalo estudiado. Se van generando parejas de números hasta encontrar una en que haya cambio de signo: entonces tiene que haber una raíz en ese intervalo. Se reduce allí el intervalo de búsqueda, y esta prosigue hasta que la distancia entre puntos sea menor que una cantidad dada.