ARREGLOS Y FUNCIONES C#, FernandoCruz

Arreglos en C#

Los arreglos en C# (también conocidos como Arrays) al igual que en C/C++, son indexados iniciando en cero (0). La forma de trabajo es muy similar a la mayoría de lenguajes pero hay lagunas diferencias que notarán.

Como Declarar e Inicializar un Arreglo en C#
Cuando vayamos a declarar un arreglo debemos colocar los corchetes después de tipo de dato. En C/C++ se estila poner los corchetes después del identificador, eso causa un error de compilación en C#-
Declaración de un Arreglo de tipo Vector en C#
        //Declaración erronea
        int valores[];
        //Declaración valida
        int[] valores;


En C# podemos indicar el tamaño del arreglo luego de la declaración. Esto nos permite decidir que tamaño va a tener el arreglo según lo que necesitemos. 


        int[] valores; //valores sin inicializar
        valores = new int[100];  //100 elementos
        valores = new int[20];  //ahora contiene 20 elementos

Arreglos Multi-dimensionales
En C# también podemos declarar arreglos multidimensionales, aquí unos ejemplos:

//Arreglos unidimensionales o de dimensión simple
        int[] valores1;                       //sin inicializar
        int[] valores2 = new int[50];



        //Arreglos multidimensionales
        int[,] valores1;                    //sin inicializar
        int[,] valores2 = new int[3,7];
        int[,,] valores3 = new int[3,4,2]; //Arreglo de tres dimensiones


        //Arreglo de arreglos
        int[][] matriz;                   //sin inicializar
        //Los arreglos de arreglos se inicializan de manera diferente
        int[][] matriz = new int[3][];
        for (int i = 0; i < matriz.Length; i++)
        {
            matriz[i] = new int[4];
        }


ARRAYS

Antes de comenzar a explicaros con mayor claridad qué es un array quiero advertir nuevamente a los programadores de C/C++: En C#, aunque parecidos, los arrays son diferentes tanto semántica como sintácticamente, de modo que te recomiendo que no pases por alto esta entrega.

Bien, una vez hechas todas las aclaraciones previas, creo que podemos comenzar. Un array es un indicador que puede almacenar varios valores simultáneamente. Cada uno de estos valores se identifica mediante un número al cual se llama índice. Así, para acceder al primer elemento del array habría que usar el índice cero, para el segundo el índice uno, para el tercero el índice dos, y así sucesivamente. Que nadie se preocupe si de momento todo esto es un poco confuso, ya que lo voy a ir desmenuzando poco a poco. Vamos a ver cómo se declara un array:

tipo[] variable;

Bien, como ve es muy parecido a como se declara una variable normal, sólo que hay que poner corchetes detrás del tipo. Los programadores de C/C++ habrán observado inmediatamente la diferencia sintáctica. En efecto, en la declaración de un array en C# los corchetes se colocan detrás del tipo y no detrás de la variable. Esta pequeña diferencia sintáctica se debe a una importante diferencia semántica: aquí los arrays son objetos derivados de la clase System.Array. Por lo tanto, y esto es muy importante, cuando declaramos un array en C# este aún no se habrá creado, es decir, no se habrá reservado aún memoria para él. En consecuencia, los arrays de C# son todos dinámicos, y antes de poder usarlos habrá que instanciarlos, como si fuera cualquier otro objeto. Veamos un breve ejemplo de lo que quiero decir:

string[] nombres; // Declaración del array
nombres = new string[3]; // Instanciación del array

En efecto, tal como puede  apreciar, el array nombres será utilizable únicamente a partir de su instanciación. En este ejemplo, el número 3 que está dentro de los corchetes indica el número total de elementos de que constará el array. No los equivoquémos, pues que todos los arrays de C# están basados en cero, esto es, el primer elemento del array es cero. Por lo tanto, en este caso, el último elemento sería 2 y no 3, ya que son tres los elementos que lo componen (0, 1 y 2). Veamos un ejemplo algo más completo y después lo comentamos:

using System;

namespace Arrays
{
    class ArraysApp
    {
        static void Main()
        {
            string[] nombres; // Declaración del array
            ushort num=0;

            do
            {
                try
                {
                    Console.Write("¿Cuántos nombres vas a introducir? ");
                    num=UInt16.Parse(Console.ReadLine());
                }
                catch
                {
                    continue;
                }
            } while (num==0);

            nombres=new string[num]; // Instanciación del array

            for (int i=0; i<num; i++)
            {
                Console.Write("Escribe el nombre para elemento {0}: ", i);
                nombres[i]=Console.ReadLine();
            }

            Console.WriteLine("Introducidos los {0} nombres", num);
            Console.WriteLine("Pulsa INTRO para listarlos");

            string a=Console.ReadLine();

            for (int i=0; i<num; i++)
            {
                Console.WriteLine("Elemento {0}: {1}", i, nombres[i]);
            }

            a=Console.ReadLine();
        }
    }
}

Veamos ahora la salida en la consola (en rojo, como siempre, lo que se ha escrito durante la ejecución del programa):

¿Cuántos nombres vas a introducir? 3
Escribe el nombre para el elemento 0: Juanito
Escribe el nombre para el elemento 1: Jaimito
Escribe el nombre para el elemento 2: Joselito
Introducidos los 3 nombres
Pulsa INTRO para listarlos
Elemento 0: Juanito
Elemento 1: Jaimito
Elemento 2: Joselito




Funciones en C#
Una función es un procedimiento que, adicionalmente, devuelve un valor como resultado de su ejecución.

La ventaja de las funciones es que pueden utilizarse en asignaciones, expresiones matemáticas, etc.

Bien, pues C# ataja este escenario mediante las funciones locales. Se declaran en el interior del miembro desde las que las usamos, y sólo son visibles desde él:
public int CalculateSomething(int n, int m)
{
    var fixedN = FixValue(n);
    var fixedM = FixValue(m);
    return fixedN+fixedM;

    int FixValue(int k)
    {
        return k < 0 ? 0 : k < 11 ? 10 : k < 21 ? 20 : k % 20;
    }
}
Observad que la sintaxis para declararlas es muy intuitiva, idéntica a los métodos tradicionales excepto en que no incluyen modificadores de visibilidad (private, public…), y su ubicación en el interior de un bloque de código.

Pero como estamos en la era de los expression bodied members y en este caso la función retorna simplemente la evaluación de una expresión, también podemos escribirlo usando este dulce azucarillo sintáctico. Fijaos que parece una lambda (Func<T1, T2>), pero no lo es:
public int CalculateSomething(int n, int m)
{
    var fixedN = FixValue(n);
    var fixedM = FixValue(m);
    return fixedN+fixedM;

    int FixValue(int k) => k < 0 ? 0 : k < 11 ? 10 : k < 21 ? 20 : k % 20;
}
Algunas características interesantes de las funciones locales
Las funciones locales pueden ser definidas en cualquier punto del código de métodos, constructores, getters o setters, ya sea antes o después de ser utilizadas. Es decir, aunque no es muy recomendable por los problemas de legibilidad que introduce, el siguiente código compilaría bien:
public int Foo()
{
    var x = Bar();

    int Bar()     
    {
        ...
    }

    var y = Bar();
    return x + y;
}
Dado que se encuentran en un ámbito concreto, pueden capturar variables de éste y utilizarlas en su interior, como en el siguiente ejemplo:
public int Foo()
{
    var x = 2;
    return Multiply(3); // Returns 6

    int Multiply(int y) => x * y;
}
Como era de esperar, también pueden ser asíncronas:

public async Task<int> Foo(int x)
{
    return x * await GetValue();

    async Task<int> GetValue()
    {
        await Task.Delay(1000);
        return 2;
    }
}
Y aunque probablemente tenga poca utilidad práctica, como curiosidad, es interesante saber que pueden ser declaradas en bloques de código específicos, restringiendo aún más su ámbito de uso:

public int Foo(int a, int b, int c)
{
    if (a > b)
    {
        return Multiply(a, b);
        int Multiply(int x, int y) => x * y;
    }
    return Multiply(b, c); // Compilation error!!
}
¿Y puedo usar esta característica en Visual Studio 2010?
Estrictamente hablando sí se puede, aunque la experiencia no será del todo satisfactoria. Veamos cómo hacerlo partiendo de un código de una aplicación de consola como el siguiente, creado desde Visual Studio 2015, que inicialmente no compilará:

class Program
{
    static void Main(string[] args)
    {
        var four = Sum(2, 2);
        Console.WriteLine(four);
        Console.ReadLine();

        int Sum(int x, int y) => x + y;
    }
}





Programas de arreglos

instrucciones para que sirve cada herramienta de los programas a continuación
Explicación ejemplos
1.      Declaramos la condición int que es de numero entero y la variable n.
2.      Declaramos string en la variable para letra
3.      console.writeline  es para que muestre en pantalla y pida el número de deseamos ingresar
4.      declaramos la variable linea = (Console.ReadLine()); que esto nos va servir para capturar ingresado
5.      Declaramos el ciclo for (int i =1; i<=n; i++)
6.      Int i = 1; que eso se significa que es de donde va empezar en conteo.
7.      I <=n; que hasta donde se acabará el conteo.
8.      I++ es quiere decir que se sumara de uno en uno.
9.      Cuando se ingrese lo que se le pida esta condición se ejecutara.
10.   declaramos la condición if (1/5==0) no en todos los programas se usa.
11.  Esta condición se ejecutará cuando ingresemos el número si no pasara la siguiente acción.
esto es lo basico que tiene que saber.

Programa que guardar los sueldos de 5 operarios en un arreglo de tipo vector
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PruebaVector1
{
    class PruebaVector1
    {
        private int[] sueldos; //Declaramos un vector

        public void Cargar()
        {
            sueldos = new int[6]; //Inicializamos el vector en 5
            for (int f = 1; f <= 5; f++)
            {
                Console.Write("Ingrese sueldo del operario "+f+": ");
                String linea;
                linea = Console.ReadLine();
                sueldos[f] = int.Parse(linea); //Asignamos los 5 sueldos al vector
            }
        }
        //Muestra los sueldos de los operarios en el vector sueldos[f]
        public void Imprimir()
        {
            Console.Write("Los 5 sueldos de los aperarios \n");
            for (int f = 1; f <= 5; f++)
            {
                Console.Write("["+sueldos[f]+"] ");
            }
            Console.ReadKey();
        }
        //main principal
        static void Main(string[] args)
        {
            PruebaVector1 pv = new PruebaVector1();
            pv.Cargar();
            pv.Imprimir();
        }
    }
} 
Al ejecutar el código muestra el siguiente resultado


Para la declaración de un vector le antecedemos al nombre los corchetes abiertos y cerrados:

private int[] sueldos;

Lo definimos como atributo de la clase ya que lo utilizaremos en los dos métodos.
En el método de Cargar lo primero que hacemos es crear el vector (en C# los vectores son objetos por lo que es necesario proceder a su creación mediante el operador new):

sueldos = new int[6];


Programa que permita almacenar los sueldos de los empleados agrupados por turno.

Imprimir los gastos en sueldos de cada turno.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PruebaVector
{
    class PruebaVector3
    {
        private float[] turnoM; //Declaramos un vector para el turno mañana
        private float[] turnoT; //Declaramos un vector para el turno tarde

        public void Cargar()
        {
            string linea;
            turnoM = new float[4]; //Asignamos al vector una de longitud 4
            turnoT = new float[4]; //Asignamos al vector una de longitud 4
            Console.WriteLine("Sueldos de empleados del turno de la mañana.");
            for (int f = 0; f < 4; f++)
            {
                Console.Write("Ingrese sueldo "+(f+1)+": ");
                linea = Console.ReadLine();
                turnoM[f] = float.Parse(linea); //Asignamos valores al vector turno mañana
            }
            Console.WriteLine("Sueldos de empleados del turno de la tarde.");
            for (int f = 0; f < 4; f++)
            {
                Console.Write("Ingrese sueldo "+(f+1)+": ");
                linea = Console.ReadLine();
                turnoT[f] = float.Parse(linea); //Asignamos valores al vector turno tarde
            }
        }

        public void CalcularGastos()
        {
            float man = 0;
            float tar = 0;
            for (int f = 0; f < 4; f++)
            {
               man = man + turnoM[f]; //Realizamos la suna de los valores del vector turno Mañana
               tar = tar + turnoT[f]; //Realizamos la suna de los valores del vector turno Tarde
            }
            Console.WriteLine("Total de gastos del turno de la mañana:" + man);
            Console.WriteLine("Total de gastos del turno de la tarde:" + tar);
            Console.ReadKey();
        }

        static void Main(string[] args)
        {
            PruebaVector3 pv = new PruebaVector3();
            pv.Cargar();
            pv.CalcularGastos();
        }
    }
}

Al ejecutar el código muestra el siguiente resultado



programa que muestre el curso que obtuvo el mayor promedio general.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PruebaVector6
{
    class PruebaVector6
    {
        private int[] quimica; //Declaramos un vector para el curso Química
        private int[] fisica; //Declaramos un vector para el curso Física
        private int[] vecSuma;//Declaramos un vector para la suma

        public void Cargar()
        {
            quimica = new int[5]; //Asignamos una longitud de 5 al vector química
            fisica = new int[5]; //Asignamos una longitud de 5 al vector Física 
            Console.WriteLine("Ingrese notas del curso Quimica");
            for (int f = 0; f < 5; f++)
            {
                Console.Write("Ingrese nota "+(f+1)+": ");
                string linea;
                linea = Console.ReadLine();
                quimica[f] = int.Parse(linea);
            }
            Console.WriteLine("Ingrese notas del Fisica");
            for (int f = 0; f < 5; f++)
            {
                Console.Write("Ingrese nota "+(f+1)+": ");
                string linea;
                linea = Console.ReadLine();
                fisica[f] = int.Parse(linea);
            }
        }

        public void CalcularPromedios()
        {
            int suma1 = 0;
            int suma2 = 0;
            for (int f = 0; f < 5; f++)
            {
                suma1 = suma1 + quimica[f];
                suma2 = suma2 + fisica[f];
            }
            int promedioa = suma1 / 5;
            int promediob = suma2 / 5;
            if (promedioa > promediob)
            {
                Console.WriteLine("El curso de Quimica tiene un promedio mayor.");
            }
            else
            {
                Console.WriteLine("El curso de Fisica tiene un promedio mayor.");
            }
            Console.ReadKey();
        }

        static void Main(string[] args)
        {
            PruebaVector6 pv = new PruebaVector6();
            pv.Cargar();
            pv.CalcularPromedios();
        }
    }
}

Al ejecutar el código muestra el siguiente resultado


Programas de funciones

Comentarios