\chapter{Sentencias de condición y de repetición}

\section{Sentencias de Condición}

\subsection{if-else}
En cualquier lenguaje de programación es habitual tener que comprobar si se cumple una cierta condición. La forma normal de conseguirlo es empleando una construcción de la forma:

\begin{verbatim}
    SI   condición_se_cumple   ENTONCES   pasos_a_dar
    SINO pasos_alternos
\end{verbatim}

Esta construcción se encuentra en la mayoría de los lenguajes y es conocida como intrusiones condicionales. En el caso de C, la forma exacta será empleando if (si, en inglés), seguido por la condición entre paréntesis, e indicando finalmente entre llaves los pasos que queremos dar si se cumple la condición, así :

    if (condición)  { sentencias }

Por ejemplo,

\begin{verbatim}
    if (x == 3)  {
      printf( "El valor es correcto\n" );
      resultado = 5;
    }
\end{verbatim}

Nota: Si solo queremos dar un paso en caso de que se cumpla la condición, no es necesario emplear llaves. Las llaves serán imprescindibles solo cuando haya que hacer varias cosas:

\begin{verbatim}
    if (x == 3)
      printf( "El valor es correcto\n" );
\end{verbatim}

Una primera mejora, que también permiten muchos lenguajes de programación, es indicar qué hacer en caso de que no se cumpla la condición. Sería algo parecido a

\begin{verbatim}
    SI  condición_a_comprobar  ENTONCES  pasos_a_dar  
    EN_CASO_CONTRARIO  pasos_alternativos
\end{verbatim}

\noindent
que en  C escribiríamos así:

\begin{verbatim}
    if (condición)  { sentencias1 }   else   { sentencias2 }
\end{verbatim}

Por ejemplo,

\begin{verbatim}
    if (x == 3)  {
      printf( "El valor es correcto\n" );
      resultado = 5;
    }
    else  {
      printf( "El valor es incorrecto\n" );
      resultado = 27;
    }

\end{verbatim}

\subsubsection{Ejemplo}
El siguiente ejemplo  permite calcular dado tres números cual es el mayor y cual es el menor de ellos.

\begin{verbatim}
// Ejemplo mayor_menor.cpp

/**
 * Title: Mayor y menor
 * Description: Dados tres numeros dice cual es el mayor y cual el menor
 * Copyright: Copyright (c) 2003
 * Company: UMSNH
 * author Dr. Felix Calderon Solorio
 * version 1.0
 */


#include <stdio.h>

int main ()
{
  int a, b, c, d;

  a = 4; b = 2; c = 3;
  d = (a > b) ?  a : b;
  d = (d > c) ?  d : c;

  printf("el Mayor es %d\n", d);


  // otra forma

  if(a> b) d = a;
  else d = b;
  if(d< c) d = c;

  printf("el Mayor es %d\n", d);

  return 0;
}

\end{verbatim}

\subsubsection{Ejemplo}
Este ejemplo nos permite determinar dado los tres lados de un triángulo, si es un triángulo Equilátero, Escaleno  Isósceles

\begin{verbatim}
/* 
 * File:   triangulos_1.c
 * Author: felix
 *
 * Created on 15 de septiembre de 2011, 11:25
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * Determinar el tipo de triangulo a partir de los lados a b y c
 */
int main(int argc, char** argv) {
    float a,b,c;
    
    printf("Por favor dame el primer lado a =  ");
    scanf("%f", &a);
    printf("Por favor dame el segundo lado b = ");
    scanf("%f", &b);
    printf("Por favor dame el tercer lado c =  ");
    scanf("%f", &c);
    
    printf("\n");
    
    // Comienza calculando la desigualdad del triangulo ya que
    // a + b > = c para todos los lados
    
    if((a+b > c) && (a+c >b) && (b+c >a)) {
        // en el caso de un triangulo equilatero
        if(a==b && a==c) printf("Es un triangulo Equilatero\n");
        // en el caso de un triangylo Isoseles
        else if (a==b || b==c || a==c) printf("Es un triangulo Isoseles\n");
        // en el caso de un triangulo escaleno        
        else printf("Es un triangulo Escaleno\n");
    }
    else printf("Para los valores que me diste no forman un triangulo\n");
    
    return (0);
}
\end{verbatim}

\subsubsection{Ejemplo}
Otro ejemplo basado en triángulos es el siguiente. En este se calcula además del tipo de triángulo los ángulos internos del mismo

\begin{verbatim}
// Ejemplo triangulos.c

/**
 * Title: Tipos de triangulos
 * Description: Programa para determinar el tipo de triangulo dados tres lados
 * Copyright: Copyright (c) 2003
 * Company: UMSNH
 * author Dr. Felix Calderon Solorio
 * version 1.0
 */

#include <stdio.h>
#include <math.h>

int main()
{
  double a = 1, b = 1, c = 1; // tamaño de los lados
  double A, B, C; // angulos
  double suma;
  double PI = 3.14159265358979323846;

  A = acos( (b * b + c * c - a * a) / (2 * b * c)) * 180 / PI;
  B = acos( (a * a + c * c - b * b) / (2 * a * c)) * 180 / PI;
  C = acos( (a * a + b * b - c * c) / (2 * a * b)) * 180 / PI;

  suma = A + B + C;

  printf("Los lados son   = [ %f %f %f ]\n", a, b, c);
  printf("Los angulos son = [ %f %f %f ]\n", A, B, C);
  printf("La suma de sus angulos es = %f\n", suma);


  if (abs(suma - 180) < 1e-6) {
    if (a == b && b == c)
      printf("Es un triangulo equilatero \n");
    else {
      if (A == 90 || B == 90 || C == 90)
        printf("Es un triangulo rectangulo \n");
      else {
        if (a == b || b == c || a == c)
          printf("Es un triangulo isoceles \n");
        else {
          if (A != B && B != C && C != A)
            printf("Es un triangulo escaleno \n");
        }
      }
    }
  }
  else
    printf("Estos valores no forman un triangulo \n");

  return 0;
}
\end{verbatim}

\subsubsection{Ejemplo}
Para una ecuación cuadrática de la forma $f(x)=Ax^2+Bx + C $, calcular los de $x$ que hacen $f(x)=0$ utilizando la formula general

\begin{equation*}
x = \frac{-B \pm  \sqrt{B^2 - 4 A C}}{2 A}
\end{equation*}  

\noindent
La solución en C queda

\begin{verbatim}
// Ejemplo eq_cuadratica.cpp

/**
 * Title: Raices de un Polinomio
 * Description: este ejemplo calcula las raices de una ecuacion de segundo grado
 * Copyright: Copyright (c) 2003
 * Company: UMSNH
 * author Dr. Felix Calderon Solorio
 * version 1.0
 */

#include <stdio.h>
#include <math.h>

int main()
{

  double A=9, B=6, C=4;
  double X1=0, X2=0, G=0, I=0, D=0;

  D=(B*B-(4*A*C));

  if (D>0)
  {
    // si las raices son positivas

    X1=(-B+sqrt(D))/(2*A);
    X2=(-B-sqrt(D))/(2*A);
    printf("X1 = %f\n", X1);
    printf("X2 = %f\n", X2);
  }
  else
  {
    // si las raices son negativas
    G=-B/(2*A);
    I=sqrt(-D)/(2*A);
    printf("X1 = %f, %f j\n", G, I);
    printf("X2 = %f, %f j\n", G, -I);
  }

  return 0;
}
\end{verbatim}

\subsubsection{Ejemplo}
Un objeto es lanzado con una velocidad inicial $v_i = 20$ m/s hacia arriba. Determinar a) La altura máxima a la que llega y b) los tiempos en que el objeto esta a la mitad de la altura máxima.

\begin{verbatim}
/* 
 * File:   caida_libre.c
 * Author: felix
 *
 * Created on 15 de septiembre de 2011, 10:47
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char** argv) {
    float vi=20, g = 9.8, hmax;
    
    float A, B, C, D, t1, t2, aux;
    
    // a) Utilizando h = (vi^2 - vf^2)/(2*g)  la hmax ocurre cuando vf = 0
    
    hmax = vi*vi/2.0/g;
    printf("La velocidad inicial es %f\n", vi);
    printf("La altura Maxima es %f\n\n", hmax);
    
    // b) Para h = hmax/2 Resolvemos
    // y = vi*t - 0.5*g*t^2 con h = hmax/2
    // 0.5*g t^2 - vi t + hmax/2 = 0
    
    A = 0.5*g;
    B = -vi;
    C= hmax/2.0;
    
    D = B*B - 4.0*A*C;
    
    if(D < 0) printf("No existe solucion al problema\n") ;
    else {
        t1 = (-B + sqrt(D))/2.0/A;  // t = (- B +- (B^2 - 4AC)^0.5)/(2.0*A)
        t2 = (-B - sqrt(D))/2.0/A;
        
        if(t1>t2) {
            aux = t1;
            t1 = t2;
            t2 = aux;
        }
        
        printf("El objeto esta a la altura h = %f  \n\n", C);
        printf("Cuando sube en t1 = %f y cuando baja en t2 = %f\n", t1, t2);
    }
    
    return (0);
}
\end{verbatim}

\subsubsection{Ejemplo}

Determinar si la suma de un número de 4 digitos es igual a 21

\begin{verbatim}
/* 
 * File:   suma_21.c
 * Author: felix
 *
 * Created on 20 de septiembre de 2011, 18:44
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * Escribir un programa que permita calcular si las ultimas 4 cifras de un 
 * numero suma 21
 */

int main(int argc, char** argv) {
    int n1, n2, n3, n4, suma, n, n0;
    printf("Dame un numero entero ");
    scanf("%d", &n0);
    
    n = n0%10000;    // se queda solamente con la ultimas 4 cifras de n
    
    n1 = n/1000;    // calcula n1 como la division entera
    n %= 1000;      // se queda solamente con las ultimas 3 cifras de n
    
    n2 = n/100;     // calcula n2 como la division entera
    n %= 100;       // se queda solamente con las ultimas 2 cifras de n
    
    n3 = n/10;      // calcula n3 como la division entera
    n4 = n%10;      // se queda con el utimo digito
    
    suma = n1+n2+n3+n4;
    if(suma == 21) printf("La suma es igual a 21\n");
    else printf("Sigue intentando la suma es %d\n", suma);
    
    return (0);
}

\end{verbatim}



\subsection{switch}

Si queremos comprobar varias condiciones, podemos utilizar varios if - else - if - else - if encadenados, pero tenemos una forma más elegante en C de elegir entre distintos valores posibles que tome una cierta expresión.  Su formato es :

\begin{verbatim}
  switch (expresion) {
    case valor1: sentencias1; break;
    case valor2: sentencias2; break;
    case valor3: sentencias3; break;
    ...                                  // Puede haber más valores
}
\end{verbatim}

\subsubsection{Ejemplo}
Como ejemplo podemos ver la siguiente implementación en C, que permite calcular cual es el \'ultimo dígito de un número dado

\begin{verbatim}
/* 
 * File:   switch.c
 * Author: felix
 *
 * Created on 13 de septiembre de 2011, 19:57
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * Este programa calcula las unidades en un numero entero
 */
int main(int argc, char** argv) {
    int d = 243;
    
    switch(d%10) {
        case 0: printf("cero ");   break;
        case 1: printf("uno ");    break;
        case 2: printf("dos ");    break;
        case 3: printf("tres ");   break;
        case 4: printf("cuatro "); break;
        case 5: printf("cinco ");  break;
        case 6: printf("seis ");   break;
        case 7: printf("siete ");  break;
        case 8: printf("ocho ");   break;
        case 9: printf("nueve ");  break;
        default : ;
    }
    
    printf("Unidades\n");
    
    return (0);
}


\end{verbatim}

Es decir, después de la orden switch indicamos entre paréntesis la expresión que queremos evaluar. Después, tenemos distintos apartados, uno para cada valor que queramos comprobar; cada uno de estos apartados se precede con la palabra case, indica los pasos a dar si es ese valor el que se da, y terminar con break.

Un ejemplo sería:

\begin{verbatim}
  switch ( x * 10) {
    case 30: printf( "El valor de x era 3" ); break;
    case 50: printf( "El valor de x era 5" ); break;
    case 60: printf( "El valor de x era 6" ); break;
}
\end{verbatim}

también podemos indicar qué queremos que ocurra en el caso de que el valor de la expresión no sea ninguno de los que hemos detallado:

\begin{verbatim}
  switch (expresion) {
    case valor1: sentencias1; break;
    case valor2: sentencias2; break;
    case valor3: sentencias3; break;
    ...                                  // Puede haber más valores
    default: sentencias;                 // Opcional: valor por defecto
}
\end{verbatim}

Por ejemplo, así:

\begin{verbatim}
  switch ( x * 10) {
    case 30: printf( "El valor de x era 3" ); break;
    case 50: printf( "El valor de x era 5" ); break;
    case 60: printf( "El valor de x era 6" ); break;
    default: printf( "El valor de x no era 3, 5 ni 6" ); break;
}
\end{verbatim}

Podemos conseguir  que en varios casos se den los mismos pasos, simplemente eliminado la orden ``break'' de algunos de ellos. Así, un ejemplo algo más completo podría ser:

\begin{verbatim}
  switch ( x ) {
    case 1:
    case 2:
    case 3:
        printf( "El valor de x estaba entre 1 y 3" );
        break;
    case 4:
    case 5:
        printf( "El valor de x era 4 o 5" );
        break;
    case 6:
        printf( "El valor de x era 6" );
        valorTemporal = 10;
        printf( "Operaciones auxiliares completadas" );
        break;
    default:
        printf( "El valor de x no estaba entre 1 y 6" );
        break;
}
\end{verbatim}

\subsubsection{Ejemplo}

El siguiente ejemplo permite calcular, dada una letra en que rango se encuentra.
\begin{verbatim}
/* 
 * File:   rango_letras.c
 * Author: felix
 *
 * Created on 13 de septiembre de 2011, 20:06
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * Uso de la sentencia switch. El programa clasifica una letra por rangos
 */

int main(int argc, char** argv) {
    
    char c;
    printf("Dame un caracter "); 
    
    c = getchar();
    
    if(c >= 'A' && c <= 'Z') c += 32;
    
    switch(c) {
        case 'a' : 
        case 'b' :
        case 'c' :
        case 'd' : printf("La letra esta entre A y D\n"); break;
        case 'e' :
        case 'f' :
        case 'g' :
        case 'h' : printf("La letra esta entre E y H\n"); break;
        case 'i' :
        case 'j' :
        case 'k' :
        case 'l' : printf("La letra esra ebtre I y L\n"); break;
        case 'm' :
        case 'n' :
        case 'o' :
        case 'p' : printf("La letra esra ebtre M y P\n"); break;
        case 'q' :
        case 'r' :
        case 's' :
        case 't' : printf("La letra esra ebtre Q y T\n"); break;
        case 'u' :
        case 'v' :
        case 'w' :
        case 'x' : printf("La letra esra ebtre U y X\n"); break;
        case 'y' :
        case 'z' : printf("La letra esra ebtre X y Z\n"); break;
        default : printf("No es un caracter valido\n");
    }
    
    return (0);
}
\end{verbatim}

Un poco más adelante propondremos ejercicios que permitan afianzar todos estos conceptos.

\subsection{Operador Condicional}

Existe una construcción adicional, que permite comprobar si se cumple una condición y devolver un cierto valor según si dicha condición se cumple o no. Es lo que se conoce como el ``operador condicional (?)'':

\begin{verbatim}
    condicion ? resultado_si cierto : resultado_si_falso
\end{verbatim}

Es decir, se indica la condición seguida por una interrogación, después el valor que hay que devolver si se cumple la condición, a continuación un símbolo de ``dos puntos'' y finalmente el resultado que hay que devolver si no se cumple la condición.

Es frecuente emplearlo en asignaciones (aunque algunos autores desaconsejan su uso porque puede resultar menos legible que un ``if''), como en este ejemplo:

    x = (a == 10) ? b*2 : a ;

En este caso, si a vale 10, la variable tomará el valor de b*2, y en caso contrario tomará el valor de a. Esto también se podría haber escrito de la siguiente forma, más larga pero más legible:

\begin{verbatim}
    if (a == 10)  x = b*2; else x = a;
\end{verbatim}

El siguiente es un ejemplo donde se utilizan las expresiones condicionales.

\begin{verbatim}
/* 
 * File:   expresion_condicional.c
 * Author: felix
 *
 * Created on 13 de septiembre de 2011, 13:06
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * Este es un ejemplo de como utilizar expresiones condicionales.
 */
int main() {
    
    int x =1, y;
    
    /*
     * La condicional 
    */
    
    if(x==1) y = 20;
    else y = 10;
    
    printf("y = %d\n", y);
    
    /*
     * se puede escribir como 
     */
   
    y=0;
    
    y = (x==1) ? 20 : 10;        
    printf("y = %d\n", y);
    
    /*
     *Otro ejemplo es
     */
    
    if(x==1) puts("en Auto");
    else puts("en bici");
    
    /**
     *Utilizando expresiones
     */
    
    puts((x==1) ? "en Auto" : "en bici");
            
    return (0);
}
\end{verbatim}



\section{Repetición}
Con frecuencia tendremos que hacer que una parte de nuestro programa se repita (algo a lo que con frecuencia llamaremos bucle), bien mientras se cumpla una condición o bien un cierto número prefijado de veces.

\subsection{while}
C incorpora varias formas de conseguirlo. La primera que veremos es la orden while, que hace que una parte del programa se repita mientras se cumpla una cierta condición. Su formato será:

\begin{verbatim}
    while (condición) {
        sentencia 1;
        sentencia 2;
        ...
     }
\end{verbatim}

Es decir, la sintaxis es similar a la de if, con la diferencia de que aquella orden realizaba la sentencia indicada una vez como máximo (si se cumple la condición), pero while puede repetir la sentencia más de una vez (mientras la condición sea cierta). Al igual que ocurría con if, podemos realizar varias sentencias seguidas (dar más de un paso) si las encerramos entre llaves:

\begin{verbatim}
    x = 20;
    while ( x > 10) {
      printf("Aun no se ha alcanzado el valor limite\n");
      x --;
    }
\end{verbatim}

\subsection{do-while}
Existe una variante de este tipo de bucle. Es el conjunto do..while, cuyo formato es:

\begin{verbatim}
    do {
      sentencia1;
      sentencia2;
      ...
    } while (condición)
\end{verbatim}

En este caso, la condición se comprueba al final, lo que quiere decir que las ``sentencias'' intermedias se realizarán al menos una vez, cosa que no ocurría en la construcción anterior (un único while antes de las sentencias), porque si la condición era falsa desde un principio, los pasos que se indicaban a continuación de while no llegaban a darse ni una sola vez.

Un ejemplo típico de esta construcción ``do..while'' es cuando queremos que el usuario introduzca una contraseña que le permitirá acceder a una cierta información:

\begin{verbatim}
    do {
      printf("Introduzca su clave de acceso\n");
      scanf("%f", &claveIntentada);  // LeerDatosUsuario realmente no existe
    } while (claveIntentada != claveCorrecta)
\end{verbatim}

En este ejemplo hemos la función scanf para leer un número flotante. 


\subsection{for}
Una tercera forma de conseguir que parte de nuestro programa se repita es la orden for. La emplearemos sobre todo para conseguir un número concreto de repeticiones.  Su formato es

\begin{verbatim}
    for ( valor_inicial ; condicion_continuacion ; incremento ) {
      sentencias1;
      sentencias2;
      ...
    }
\end{verbatim}

(es decir, indicamos entre paréntesis, y separadas por puntos y coma, tres Ordenes: la primera dará el valor inicial a una variable que sirva de control; la segunda orden será la condición que se debe cumplir para que se repitan las sentencias; la tercera orden será la que se encargue de aumentar -o disminuir- el valor de la variable, para que cada vez quede un paso menos por dar).

Esto se verá mejor con un ejemplo. podríamos repetir 10 veces un bloque de Ordenes haciendo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      ...
    }
\end{verbatim}

O bien podríamos contar descendiendo desde el 20 hasta el 2, con saltos de 2 unidades en 2 unidades, así:

\begin{verbatim}
    for ( j = 20 ; j > 0 ; j -= 2 )
      printf( "%d\n", j );
\end{verbatim}

Nota: se puede observar una equivalencia casi inmediata entre la orden for y la orden while. Así, el ejemplo anterior se podría reescribir empleando while, de esta manera:

\begin{verbatim}
    j = 20;
    while ( j > 0 )
      printf( "%d\n", j );
      j -= 2;
    }
\end{verbatim}

Precauciones con los bucles: Casi siempre, nos interesará que una parte de nuestro programa se repita varias veces (o muchas veces), pero no indefinidamente. Si planteamos mal la condición de salida, nuestro programa se puede quedar colgado, repitiendo sin fin los mismos pasos.


Se puede modificar un poco el comportamiento de estos bucles con las ordenes break y continue.

La sentencia break hace que se salten las instrucciones del bucle que quedan por realizar, y se salga del bucle inmediatamente. Como ejemplo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      printf( "Comenzada la vuelta " );
      printf( "%d\n", i );
      if (i==8)  break;
      printf( "Terminada esta vuelta\n" );
    }
    printf( "Terminado\n"  );
\end{verbatim}

En este caso, no se mostraría el texto Terminada esta vuelta para la pasada con i=8, ni se darían las pasadas de i=9 e i=10, porque ya se ha abandonado el bucle.

La sentencia continue hace que se salten las instrucciones del bucle que quedan por realizar, pero no se sale del bucle sino que se pasa a la siguiente iteración (la siguiente vuelta o pasada). Como ejemplo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      printf( "Comenzada la vuelta\n" );
      printf( "%d\n", i );
      if (i==8)  continue;
      printf( "Terminada esta vuelta\n" );
    }
    printf( "Terminado\n"  );
\end{verbatim}

En este caso, no se mostraría el texto Terminada esta vuelta para la pasada con i=8, pero si se darían la pasada de i=9 y la de i=10.

también esta la posibilidad de usar una etiqueta para indicar donde se quiere saltar con break o continue. Solo se debería utilizar cuando tengamos un bucle que a su vez está dentro de otro bucle, y queramos salir de golpe de ambos. Es un caso poco frecuente, así que no profundizaremos más, pero si veremos un ejemplo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      printf( "Comenzada la vuelta\n" );
      printf( "%d\n", i );
      if (i==8)  break salida;
      printf( "Terminada esta vuelta\n" );
    }
    printf( "Terminado\n"  );
    salida:
    ...
\end{verbatim}

En este caso, a mitad de la pasada 8 se saltaría hasta la posición que hemos etiquetado como salida (se define como se ve en el ejemplo, terminada con el símbolo de dos puntos), de modo que no se escribiría en pantalla el texto Terminado (lo hemos saltado).

\subsubsection{Ejemplo}

Hacer un programa que permita calcular la siguiente sumatoria

$$
S = \sum_{i=0}^{i=64} 2^i
$$

La implementación en C queda:

\begin{verbatim}
// Ejemplo sumatoria.c

/**
 * Title: Sumatoria
 * Description: Este programa calcula la suma de 1 + 2 + 4 + 8+ 16 + ...2n
 * Copyright: Copyright (c) 2003
 * Company: UMSNH
 * author Dr. Felix Calderon Solorio
 * version 1.0
 */

#include <stdio.h>


int main ()
{
  int i=1, s=0;
  
  // utilizando for()
  
  for(i=0; i<=30; i++){
    s=((2*s) +1);
    printf("%d s=%d\n", i, s);
  }
  
  // utilizando while

  i = 1;
  s = 0;
  while(i <=30)
  {
    s=((2*s) +1);
    printf("%d s=%d\n", i, s);
    i++;
  }

  // utilizando do-while
  
  i = 1;
  s = 0;
  do
  {
    s=((2*s) +1);
    printf("%d s=%d\n", i, s);
    i++;
  }
  while (i<=30);
  return 0;
}
\end{verbatim}

\subsubsection{Ejemplo}

El siguiente ejemplo permite hacer una comparación entre la implementación utilizando for y do-while para leer una clave desde teclado.

\begin{verbatim}
/* 
 * File:   clave.c
 * Created on 22 de septiembre de 2011, 12:24
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * Simula el proceso de acceso a mediante clave a un cajero
 */
int main(int argc, char** argv) {
    int clave;
    
    // impelementacion utilizando for
    
    for(;;){
        printf("Dame tu clave ");
        scanf("%d", &clave);
        if(clave == 1234) break;
    }
    
    // implementacion con do-while
    
    do {
        printf("Remita su clave nuevamente ");
        scanf("%d", &clave);        
    } while (clave != 1234);

    printf("Bienvenido\n");
    
    return (0);
}
\end{verbatim}

\subsubsection{Ejemplo}

Escribir un programa que permita imprimir todas las combinaciones de palabra de tres letras que se pueden escribir utilizando las letras del alfabeto. Así por ejemplo la salida de este código es

AAA
AAB
AAC
...
ABA
ABC

etc.

\begin{verbatim}
/* 
 * File:   combinaciones.c
 * Author: felix
 *
 * Created on 5 de octubre de 2011, 11:27
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * 
 */
int main(int argc, char** argv) {
    int i, j, k, n=1;
    int letra = 'A';
    
    for(i=0; i<3; i++){
        for(j=0; j<3; j++){
            for(k=0; k<3; k++)
                printf("%02d.- %c%c%c \n", n++, letra +i, letra+j, letra +k);
        }
    }
    
    return (EXIT_SUCCESS);
}

\end{verbatim}

\subsubsection{Ejemplo}

Escribir un programa que permita hacer la siguiente tabulación correspondiente a la función $f(x)= x^2$


\begin{center}
\begin{tabular}{|c|c|}
	\hline
	$x$ & $f(x)$ \\
	\hline
	1 & 1 \\
	2 & 4 \\
	3 & 9 \\
	4 & 16\\
	\hline
\end{tabular}
\end{center}

\begin{verbatim}
//Ejemplo funcion.c

/**
 * <p>Title: Ejemplo de una funcion</p>
 * <p>Description: Realiza la funcion x2</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: UMSNH</p>
 * @author Dr. Felix Calderon Solorio
 * @version 1.0
 */

#include <stdio.h>

float cuadrado(float); // prototipo de funcion

int main() 
{
  int x;
    
  for(x=1; x<=10; x++)
    printf("%d^2 = %f \n", x, cuadrado(x));

  return 0;
}

// Definicion  de la funcion
  
float cuadrado(float y)
{
  return y*y;
}
\end{verbatim}



\subsubsection{Ejemplo}

Escribir un programa que permita imprimir un triángulo como el que se muestra a continuación

\noindent
*\\
**\\
***\\
****\\
*****\\
******\\
*******\\

\begin{verbatim}
/* 
 * File:   triangulo_asteriscos.c
 * Author: felix
 *
 * Created on 5 de octubre de 2011, 11:22
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * 
 */
int main(int argc, char** argv) {
    int i, j;
    
    for(i=0; i<20; i++) {
        for(j=0; j<i; j++)
            printf("*");
        printf("\n");
    }
    
    return (0);
}
\end{verbatim}

\section {Ejemplo de sucesiones e Iteración de punto fijo}

\subsection{Métodos iterativos para resolver $x=g(x)$}

Necesitamos una regla, fórmula o función $g(x)$ con la cual calcularemos temimos sucesivos, para un valor de partida $P_0$. Lo que se produce es una sucesión de valores  ${P_k}$ obtenida mediante el proceso iterativo $P_{k+1}= g(P_k)$. La sucesión se ajusta al siguiente patrón:

$$
P_1= g(P_0)
$$
$$
P_2= g(P_1)
$$
$$
P_3= g(P_2)
$$
$$
\cdots
$$
$$
P_{k+1}= g(P_k)
$$


Lo que podemos observar de ésta sucesión es que si $P_{k+1} \leftarrow P_k$ la sucesión converge a un valor, pero en el caso de que $P_{k+1}$ no tienda a $P_k$ tenemos una sucesión divergente.

\subsubsection{Ejemplo}

Dada la sucesión  $P_{k+1} = A_{k}$ con $P_0=1$, producirá:

$$
P_1= A
$$
$$
P_2= A*A=A^2
$$
$$
P_3= A* A^2= A^3
$$
$$
...
$$
$$
P_k= A^k
$$

\subsection{Métodos de punto fijo}

Un punto fijo de una función g(x) es un número real P tal que $P=g(P)$. Geométricamente hablando, los puntos fijos de una función $g(x)$ son los puntos de intersección de la curva $y=g(x)$ con la recta $y=x$.


\subsubsection{Ejemplo}

Consideremos la función $p=e^{-p}$ y damos un valor inicial $p_0 = 0.5$

La solución de esta recurrencia es:

$$
p_1= e^{-0.5} = 0.606531\\
p_2= 0.545339\\
p_3= 0.579703\\
...\\
p_k=0.567143
$$


La implementación en C es

\begin{verbatim}
/* 
 * File:   punto_fijo.c
 * Author: felix
 *
 * Created on 2 de marzo de 2012, 12:35
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char** argv) {
    int iter = 0;
    double x0, x1;
    
    x0 = x1 = 0.5;
    
    do
    {
        printf("X(%d)= %f\n", iter, x1);
        x0 = x1;
        x1 = exp(-x0);
        iter ++;
    } while (fabs((x0-x1)/x1) > 0.001);
  
    return (EXIT_SUCCESS);
}\end{verbatim}

\subsection{Solución de Sistemas no lineales}

Consideremos el caso de la funciones :
$$
f_1(x,y) = x^2 - 2x - y + 0.5
$$
$$
f_2(x,y) = x^2 + 4y^2 - 4
$$

\noindent
y queremos encontrar un método para calcular los ceros de estas funciones, es decir, los valores $x$ y $y$ que hacen $f_1(x,y) =0$ y $f_2(x,y) = 0$

Podemos resolver el sistema, utilizando el método de iteración de punto fijo. Para ello despejamos de la ecuación 1 a x:

$$
x = \frac{x^2 - y + 0.5}{2}
$$

A la segunda ecuación agregamos un termino

$$
x^2 + 4y^2 - 8y -4 = - 8y
$$
$$
y = \frac{-x^2 -4y^2 +8y + 4}{8}
$$

De esto tenemos un sistema en sucesión dado por:

$$
x_{k+1} = \frac{x_k^2 - y_k + 0.5}{2}
$$
$$
y_{k+1} = \frac{-x_k^2 -4y_k^2 +8y_k + 4}{8}
$$

La solución de esta sucesión para un valor inicial $[0,1]$ es:

\begin{tabular}{|c|c|c|}
  \hline
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
  k & x & x \\
  \hline
  0 &  0.0000 & 1.0000 \\
  1 & -0.2500 & 1.0000 \\
  2 & -0.2188 & 0.9922 \\
  3 & -0.2222 & 0.9940 \\
  4 & -0.2223 & 0.9938 \\
  5 & -0.2222 & 0.9938 \\
  6 & -0.2222 & 0.9938 \\
  \hline
\end{tabular}


\section{Salto}

El uso del GOTO implica un salto incondicional de un lugar a otro del programa. Esta práctica hace que los programas sean muy difíciles de corregir ó mantener. Si no quedara más remedio que usarlo, (y en programación estructurada SIEMPRE hay remedio) debe marcarse el destino del salto mediante un nombre seguido por dos puntos.

\begin{verbatim}
if( c == 0 )  goto OTRO_LADO;

.............................

.............................

OTRO_LADO: printf(........
\end{verbatim}

En este caso si c es cero se saltan todas las sentencias entre el if y el destino, continuándose con la ejecución del printf() . El destino puede ser posterior como anterior al GOTO invocante.




