viernes, 16 de diciembre de 2011

Arrays (matrices)

Los arrays (matrices o arreglos) permiten agrupar valores que de alguna forma necesitamos que estén relacionados entre sí.

Una matriz es una estructura de datos que contiene una serie de variables denominadas elementos de la matriz.

Declarar Arrays

En C# los arrays se definen indicando un par de corchetes en el tipo de datos.

Por ejemplo, para indicar que queremos tener un array llamado numeros para almacenar valores de tipo int, lo haremos de esta forma:

int[] numeros;

Esta declaración simplemente indica que la variable numeros "será" un array, pero aún no está inicilizada.
Para iniciarla, al menos con valores cero, podemos hacerlo de estas dos formas, dependiendo de que ya hayamos declarado previamente la variable, (primera línea), o lo queramos hacer al declararla, (segunda línea):

numeros = new int[4];

int[] num2 = new int[3];


En ambos casos debemos usar new seguido del tipo de datos y entre corchetes el número de elementos que tendrá el array. Ese número indicará el total de elementos que tendrá el array, pero debido a como .NET trata los arrays, el índice inferior será cero y el índice superior será uno menos del número de elementos que hemos indicado al crear el array.

Para asignar valores a los elementos de un array, lo haremos como con cualquier variable, pero usando los corchetes y la posición en la que queremos guardar ese valor:


num2[0] = 3;
num2[1] = 22;


Para recorrer todos los elementos que tenga un array podemos hacerlo de la forma tradicional, es decir, usando un bucle for con una variable que recorra todos los índices, en cuyo caso necesitamos averiguar el valor del índice superior del array, cosa que haremos por medio de la propiedad Length, tal como podemos ver en este código:


for (int i = 0; i < num2.Length; i++)
Console.WriteLine(num2[i]);


Como vemos, para acceder a cada uno de los valores, el elemento al que queremos acceder lo indicamos dentro de corchetes.

La otra forma de hacerlo es mediante un bucle foreach, pero debido a que foreach obtiene cada un de los valores que le indiquemos, no necesitamos acceder directamente al array, sino que usaremos el valor obtenido en cada ciclo del bucle, tal como podemos comprobar en este trozo de código:


foreach(int i in num2)
Console.WriteLine(i);


Declarar e inicializar un array


Al igual que podemos declarar variables e inicializarlas al mismo tiempo, con los arrays también podemos hacerlo, aunque la sintaxis es un poco distinta, ya que en esta ocasión debemos indicar varios valores. Esos valores los indicaremos justo después de definir el array:


string[] nombres = {"Pepe", "Juan", "Luisa"};


En este caso, cuando iniciamos el array al declararlo, no debemos indicar el número de elementos que tendrá ese array, ya que ese valor lo averiguará el compilador cuando haga la asignación. Tampoco es válido indicar el número de elementos que queremos que tenga y solo asignarle unos cuantos menos (o más), ya que se producirá un error en tiempo de compilación.

Si el array es bidimensional (o con más dimensiones), también podemos inicializarlos al declararlo, pero en este caso debemos usar doble juego de llaves:


string[,] nombres = { { "Juan", "Pepe" }, { "Ana", "Eva" } };



En este código tendríamos un array bidimensional con los siguientes valores:


nombres[0,0]= Juan
nombres[0,1]= Pepe
nombres[1,0]= Ana
nombres[1,1]= Eva


Como podemos ver en la declaración anterior, si definimos arrays con más de una dimensión, debemos indicarlas, en la declaración del tipo, usando una coma para separar cada dimensión, o lo que es más fácil de recordar: usando una coma menos del número de dimensiones que tendrá el array. En los valores a asignar, usaremos las llaves encerradas en otras llaves, según el número de dimensiones.


Cambiar el tamaño de un array


Visual C# 2010 no nos ofrece una forma fácil de cambiar el tamaño de un array, de hecho no tiene ninguna instrucción que sirva para eso.

Aunque redimensionar un array realmente no tiene ningún problema, ya que simplemente lo haremos de la misma forma que vimos anteriormente:

num2 = new int[4];

E incluso podemos asignarle nuevos valores al "redimensionarlo", usando la misma sintaxis que vimos en la sección anterior:


num2 = new int[] { 6, 7, 8, 9 };


Lo que no podemos hacer en C# es cambiar el tamaño de un array conservando el contenido anterior, algo que en otros lenguajes si es posible. La única forma de conseguirlo es hacer una copia previa de ese array, redimensionarlo al nuevo tamaño y volver a copiar el contenido anterior.
En el siguiente código podemos ver estos pasos:

int[] original = { 1, 2, 3, 4 };
int[] copia = new int[original.Length];
// Copiamos el original en la copia
original.CopyTo(copia, 0);
// Añadimos 5 elementos más
original = new int[original.Length + 5];
// Asignamos nuevamente lo copiado a partir del primer elemento
copia.CopyTo(original, 0);

Para hacer la copia hemos usado el método CopyTo, al que le indicamos el array de destino, (que previamente debe estar dimensionado con el número de elementos que recibirá), y el índice a partir del cual queremos copiar ese array, en nuestro caso le indicamos la primera posición, que como sabemos es la posición cero.




Si el array contiene valores por valor, podemos usar otro método: Clone, ya que este método devuelve una copia "superficial" del objeto en cuestión, en nuestro caso el array; esa copia superficial significa que solo copiará el contenido del array, si este tuviera referencia a objetos, no copiaría los objetos, solo las referencias, (de todo esto de los objetos y referencias a objetos nos ocuparemos en la próxima lección), pero el valor que devuelve ese método es del tipo object, es decir el tipo genérico de .NET, por tanto tendríamos que hacer una conversión al tipo array, tal como vemos en este código:


int[] copia = (int[])original.Clone();


Eliminar el contenido de un array


Una vez que hemos declarado un array y le hemos asignado valores, es posible que nos interese eliminar esos valores de la memoria, para lograrlo, en C# podemos hacerlo de dos formas:


  1. Redimensionando el array indicando que tiene cero elementos, aunque en el mejor de los casos, si no estamos trabajando con arrays de más de una dimensión, tendríamos un array de un elemento, ya que, como hemos comentado anteriormente, los arrays de .NET el índice inferior es cero.
  2. Asignar un valor null al array. Esto funciona en C# porque los arrays son tipos por referencia.

Los arrays son tipos por referencia


Como acabamos de ver, en Visual C# 2010 los arrays son tipos por referencia, y tal como comentamos anteriormente, los tipos por referencia realmente lo que contienen son una referencia a los datos reales no los datos propiamente dichos.

¿Cuál es el problema?

Veámoslo con un ejemplo y así lo tendremos más claro.


string[] nombres = { "Juan", "Pepe", "Ana", "Eva" };
string[] otros;
otros = nombres;
nombres[0] = "Antonio";
Console.WriteLine(otros[0]);


En este ejemplo definimos el array nombres y le asignamos cuatro valores. A continuación definimos otro array llamado otros y le asignamos lo que tiene nombres. Por último asignamos un nuevo valor al elemento cero del array nombres.
Si mostramos el contenido de ambos arrays nos daremos cuenta de que realmente solo existe una copia de los datos en la memoria, y tanto nombres[0] como otros[0] contienen el nombre "Antonio".

¿Qué ha ocurrido?

Debido a que los arrays son tipos por referencia, solamente existe una copia de los datos en la memoria y tanto la variable nombres como la variable otros lo que contienen es una referencia (o puntero) a los datos.

Si realmente queremos tener copias independientes, debemos hacer una copia del array utilizando el método CopyTo que ya vimos anteriormente.

Además de los métodos que hemos visto y de la propiedad Length que nos sirve para averiguar cuantos elementos tiene un array, tenemos más métodos y propiedades que podemos usar, por ejemplo para saber cuantas dimensiones tiene un array (Rank) o saber cual es el índice superior de una dimensión determinada (GetUpperBound).

Para finalizar este tema, sólo nos queda por decir, que los arrays de .NET, y por tanto los de C#, realmente son tipos de datos derivados de la clase Array y por tanto disponen de todos los miembros definidos en esa clase, aunque de esto hablaremos en la próxima lección, en la que también tendremos la oportunidad de profundizar un poco más en los tipos por referencia y en cómo podemos definir nuestros propios tipos de datos, tanto por referencia como por valor.

El método Legth


El método Length devuelve el número de elementos de un arreglo o matriz.  Nótese que los arreglos comienzan con el elemento cero (0) y siguen sucesivamente hasta el elemento superior que sería n-1.  Por ejemplo si se declara un arreglo de 10 elementos, el primer elemento será el elemento número cero de la colección y el último elemento será el elemento nueve de la colección

 

Ejemplo de uso de array en un Windows Forms



using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Arreglos
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
String[] meses = {"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio","Julio", "Agosto",
"Septiembre", "Octubre", "Noviembre", "Diciembre"};
foreach (String m in meses)
{
comboBox1.Items.Add(m);
}
comboBox1.SelectedIndex = 0;
}

private void button1_Click(object sender, EventArgs e)
{
label2.Text = "Procesando el mes de : " + comboBox1.Text;
}
}
}

En el código anterior hemos hecho una aplicación en windows forms que asigna el valor de un arreglo a un combobox.  También se muestra el uso de la instrucción foreach.  La variable m en el ciclo foreach debe ser del mismo tipo del array y lo que hace es almacenar por cada vuelta del ciclo el valor del elemento del arreglo.


El formulario tiene un botón que cuando se presiona muestra el contenido del mes seleccionado en un label (label2).


El formulario ejecutandose se mostrará más o menos como la figura siguiente:


image

No hay comentarios:

Publicar un comentario