sábado, 29 de julio de 2017

Curso de C#: control de flujo, estructuras iterativas

Bucles For 


Los bucles for van asignando valores a una variable desde un valor inicial hasta un valor final, y cuando la variable contiene un valor que está fuera del intervalo el bucle termina.

for (var=inicial;condición;siguientevalor)
{
    Instrucciones
}

CURSO DE C#: control de flujo, estructuras iterativas


Tras la sentencia for se indican las especificaciones del bucle entre paréntesis. Dichas especificaciones están divididas en tres partes separadas por punto y coma: la parte de asignación del valor inicial en primer lugar; la parte que verifica la continuidad del bucle (mediante una condición) en segundo lugar; y la parte en que se calcula el siguiente valor en tercer lugar. Ejemplo: calcular el factorial de un número dado, que se encuentra almacenado en la variable num:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}

O bien:

for (byte i=1; i<=num ; i++)
{
      fact*=i;
}

Para  que funcione, la variable fact ha de valer 1 antes de que el programa comience a ejecutar el bucle. A continuación se muestra cómo se van ejecutando estas instrucciones paso a paso:

1º paso:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}
2º paso:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}
3º paso:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}
4º paso:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}
5º paso:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}
6º paso:

for (byte i=num; i>1 ; i--)
{
      fact*=i;
}

En primer lugar se asigna a la variable i el valor de num (num vale 3), después del primer paso, el valor de i es 3. Luego se comprueba si dicha variable es mayor que 1, es decir, si 3>1. Como la condición de este paso se cumple, se ejecuta el código del bucle en el tercer paso, fact*=i, con lo que fact (que valía 1) ahora vale 3 (1*3).

En el cuarto paso se asigna el siguiente valor a i (i--), con lo que, ahora, i valdrá 2. En el quinto se vuelve a comprobar si i es mayor que 1, y como esto se cumple, el sexto paso vuelve a ejecutar el código del bucle (de nuevo, fact*=i), con lo que ahora fact vale 6 (3*2). El séptimo paso es idéntico al cuarto, es decir, se asigna el siguiente valor a la variable i (de nuevo, i--), con lo que ahora i valdría 1. El octavo paso es idéntico al quinto, comprobando por lo tanto si i es mayor que 1. Sin embargo esta vez, la condición no se cumple (1 no es mayor que 1, sino igual), por lo que la ejecución saldría del bucle y ejecutaría la siguiente línea del programa que esté fuera de él. El bucle se seguirá ejecutando siempre que la condición ( i>1 ) se cumpla, y dejará de ejecutarse cuando la condición no se cumpla. Por lo tanto, no habría sido válido poner i==2 en lugar de i>1, ya que esta condición se cumpliría únicamente cuando num valiera 2, pero no en cualquier otro caso.

Bucles for anidados


Se pueden colocar bucles for dentro de otros bucles for, con lo que se obtiene lo que se llaman los bucles for anidados.

 class BuclesAnidados
    {
        static void Main()
        {
            for (int i=1; i<=3; i++)
            {
                Console.WriteLine("Factura número {0}", i);
                Console.WriteLine("Detalles de la factura");

                for (int j=1; j<=3; j++)
                {
                    Console.WriteLine("   Línea de detalle {0}", j);
                }

                Console.WriteLine();
            }

            string a=Console.ReadLine();
        }
    }


El bucle "j" queda dentro del bucle "i", de modo que se ejecutará completo tantas veces como se itere el bucle i. La salida sería la siguiente:

Factura número 1
Detalles de la factura
   Línea de detalle 1
   Línea de detalle 2
   Línea de detalle 3

Factura número 2
Detalles de la factura
   Línea de detalle 1
   Línea de detalle 2
   Línea de detalle 3

Factura número 3
Detalles de la factura
   Línea de detalle 1
   Línea de detalle 2
   Línea de detalle 3

A continuación se muestra cómo se ejecutan estos bucles:

1º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
2º paso:

for (int i=1i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
3º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1j<=3; j++)
    {
        ...
    }
}
4º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3j++)
    {
        ...
    }
}
5º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
6º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
7º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3j++)
    {
        ...
    }
}
8º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
9º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
10º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3j++)
    {
        ...
    }
}
11º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
12º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
13º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3j++)
    {
        ...
    }
}
14º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
15º paso:

for (int i=1i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}
16º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1j<=3; j++)
    {
        ...
    }
}
17º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3j++)
    {
        ...
    }
}
18º paso:

for (int i=1; i<=3; i++)
{
    for (int j=1; j<=3; j++)
    {
        ...
    }
}

El decimonoveno paso sería igual que el sexto, el vigésimo igual que el séptimo, y así hasta terminar el bucle i. Donde están los puntos suspensivos estaría el código que forma parte del bucle j. El segundo bucle (el bucle j) se ejecuta completo para cada valor que toma la variable i del primero de los bucles. Se pueden anidar tantos bucles como sea necesario.


Bucle foreach


La instrucción foreach se ejecuta para cada elemento de un array o colección de objetos que implementa la interfaz System.Collections.IEnumerable. Sirve para recorrer una colección, pero no se puede utilizar para agregar o quitar elementos de esta, pues puede producir efectos secundarios imprevisibles. Para agregar o quitar elementos de la colección de origen, es mejor utilizar un bucle for.

Las instrucciones dentro de un foreach se ejecutan para cada elemento del array  o colección. Una vez se han recorrido todos los elementos, el control se transfiere a la siguiente instrucción fuera del bloque foreach.

En cualquier punto dentro del bloque foreach, se puede salir del bucle utilizando la palabra clave break o pasando directamente a la iteración siguiente del bucle mediante la palabra clave continue.

También se puede salir de un bucle foreach mediante las instrucciones goto, return o throw. A continuación un ejemplo de código que muestra tres ejemplos:

·         un bucle foreach típico que muestra el contenido de una matriz de enteros
·         un bucle for que hace lo mismo
·         un bucle foreach que mantiene el número de elementos de la matriz

class BucleForEach
{
    static void Main(string[] argumentos)
    {
        int[] EjAarray = new int[] { 0, 1, 1, 2, 3, 5, 8, 13 };
        foreach (int elemento in EjAarray)
        {
            System.Console.WriteLine(element);
        }
        System.Console.WriteLine();
 
 
        // Compara el bucle previo con un bucle similar for.
        for (int i = 0; i < EjAarray.Length; i++)
        {
            System.Console.WriteLine(EjAarray [i]);
        }
        System.Console.WriteLine();
 
 
        // Mantiene la cuenta de los elementos de la colección
.
        int cuenta = 0;
        foreach (int elemento in EjAarray)
        {
            cuenta += 1;
            System.Console.WriteLine("Elemento #{0}: {1}", cuenta, elemento);
        }
        System.Console.WriteLine("Numero de elementos en el array: {0}", cuenta);
    }
 
    // Salida:
    // 0
    // 1
    // 1
    // 2
    // 3
    // 5
    // 8
    // 13
 
    // 0
    // 1
    // 1
    // 2
    // 3
    // 5
    // 8
    // 13
 
    // Elemento #1: 0
    // Elemento #2: 1
    // Elemento #3: 1
    // Elemento #4: 2
    // Elemento #5: 3
    // Elemento #6: 5
    // Elemento #7: 8
    // Elemento #8: 13
    // Número de elementos en el array: 8
}


Bucles while


Un bucle while se repetirá mientras una condición determinada se cumpla, o sea, devuelva true.

while (expresión bool)
{
    Instrucciones
}

Efectivamente, las Instrucciones que hay dentro del bucle while se ejecutarán continuamente mientras la expresión de tipo booleano retorne true. Por ejemplo, un bucle while para pedir una contraseña:

    class BuclesWhile
    {
        static void Main()
        {
            string Clave="Contraseña";
            string Res="";

            while (Res!=Clave)
            {
                Console.Write("Dame la clave: ");
                Res=Console.ReadLine();
            }

            Console.WriteLine("La clave es correcta");

            string a=Console.ReadLine();
        }
    }

En este ejemplo el programa pedirá una y otra vez la clave al usuario, y cuando este teclee la clave correcta será cuando finalice la ejecución del mismo. La salida en la consola de este programa sería:

Dame la clave: A
Dame la clave: B
Dame la clave: C
Dame la clave: D
Dame la clave: E
La clave es correcta

Si la condición no se hubiera cumplido antes de ejecutar el bucle, si Res ya contuviera lo mismo que Clave antes de llegar al while, el bucle no se hubiera ejecutado ninguna vez, es decir, al comprobar que la expresión de tipo booleana retorna false, la ejecución del programa pasa a la primera línea que se encuentra a continuación del bucle. Modificando ligeramente el ejemplo anterior:

    class BucleWhile
    {
        static void Main()
        {
            string Clave="Bucl3w1l3";
            string Res=Clave;

            while (Res!=Clave)
            {
                Console.Write("Dame la clave: ");
                Res=Console.ReadLine();
            }

            Console.WriteLine("La clave es correcta");

            string a=Console.ReadLine();
        }
    }

En este caso, la salida en consola sería la siguiente:

La clave es correcta

Pues la ejecución no pasa por el bucle

Bucle Do


Estos bucles tienen mucho que ver con los bucles while. La diferencia es que estos se ejecutan siempre al menos una vez, mientras que los bucles while, pueden no ejecutarse ninguna vez. La sintaxis de los bucles "do" es:

do
{
    Instrucciones
while (expresión bool);

También hay un while y una expresión booleana, pero en este caso se encuentra al final. De este modo, la ejecución pasará siempre por las instrucciones del bucle una vez antes de evaluar dicha expresión. Un ejemplo pero cambiando el bucle while anterior por un bucle do:

    class BuclesDo
    {
        static void Main()
        {
            string Clave="M34m5fjidi";
            string Res="";

            do
            {
                Console.Write("Dame la clave: ");
                Res=Console.ReadLine();
            } while (Res!=Clave);

            Console.WriteLine("La clave es correcta");

            string a=Console.ReadLine();
        }
    }


El resultado sería el mismo que antes. La diferencia está en que aquí es indiferente lo que vaga la variable Res antes de llegar al bucle, puesto que este se va a ejecutar antes de comprobar dicho valor, y al ejecutarse, el valor de Res se sustituye por lo que se introduzca en la consola.

No hay comentarios:

Publicar un comentario