Arrays
|
Realizamos
programas para la gestión de empresas. Empresas medianas y
pequeñas. Programas de contabilidad, cartera de pedidos
clientes proveedores, facturación control de albaranes,
tesorería cartera de cobros y pagos y estadísticas.
Nuestro
agradecimiento a todos los que por unas causas o por otras
visitan nuestra web. Gestión de empresas PYMES. Curso de
programación de Visual Basic.
|
Ya estamos de nuevo
por aquí, esta vez he procurado ser un poco más rápido para que
no pierdas el hilo...
(realmente he sido demasiado rápido, pero no te acostumbres)
El problema de
escribir las entregas, no es porque no sepa que poner... a este
nivel aún se bastantes cosas... ejem! Lo que ocurre es que
normalmente suelo hacerlo en papel... quien lo diría ¿verdad?
Y es porque no tengo ordenador en mi "piso" y allí es
dónde aprovecho, por aquello de la tranquilidad, para concentrarme
en las cuatro chorradillas que voy a decir... después toca pasarlo
a "limpio" y como no soy demasiado diestro en esto de
escribir a máquina, hice rabona cuando tenía clases de
mecanografía, pues algunas veces tardo más de la cuenta. Pero como
ahora estoy en unas vacaciones "virtuales", he aprovechado
y le he mangado el portátil a mi jefe, con la excusa de que se lo
voy a limpiar de "basura" y todo ese rollo.
Vale, no me enrollo
más con mis cosillas y vamos a pasar a un tema que, por su
extensión, seguramente lo voy a dar en dos entregas.
Empezamos con la octava.
Ahora hay que ponerse "formales"...
Ya has visto todo
el tema de las variables y sabes para que sirven, (al menos así
debería ser, ya que nadie me ha preguntado sobre el tema), pero hay
veces que necesitamos más.
Imagínate que quieres saber cuantas veces por hora te rascas la
cabeza intentando comprender lo que hay en mis páginas...
Podríamos tener unas cuantas variables, una por cada hora del día,
con nombres como: Hora1, Hora2, etc. y cuando te arrasques a las 22
horas, harías esto:
Hora22 = Hora22 + 1
Con lo que aumentas en uno el contenido de la variable Hora22... y
tu dirás... ¿que problema hay? Ninguno, pero es que se me ha
ocurrido contarte esto como podría haberte contado otra cosa. Pero
imagínate que quieres sumar las veces que te has rascado la cabeza
en todo el día, podrías hacer:
VecesDia = Hora1 + Hora2 + ...+ Hora24
Tampoco hay problema, sumamos todas las variables (24 en este caso)
y guardamos el total en la variable VecesDia.
Pero la cosa se va complicando, ¿verdad? ¿No lo crees? Pues toma
un poco más de complicación:
¿Cómo harías para saber la hora en que más veces te has rascado
la cabeza?
No te doy la solución... Es demasiado largo y seguramente hasta
complicado como para ponerlo como ejemplo para que salgas de tu
incredulidad... Ahora bien, si quieres hacerlo, hazlo, pero después
no me preguntes si está bien o no... sería una pérdida de tiempo,
ya que, como vas a ver dentro de muy pocas líneas, hay una forma de
hacerlo bastante más simple.
Toda esta
retahíla, es para explicarte la forma con que el Basic, y otros
lenguajes, nos facilita la vida en tareas de este tipo... realmente
no creo que haya nadie que tenga una utilidad de este tipo, ya que
no es útil esto de saber cuantas veces nos rascamos la cabeza por
no comprender algo... ni aún cuando ese algo sea lo que yo
escribo...
Un poco de historia
(la mía)
La primera vez que me topé con los ARRAYS (de eso va esta entrega),
fue con un programa de dados, en mi querido VIC-20. Lo copié de un
libro inglés que tenía 50 juegos para el Vic-20, sabía que
funcionaba, pero no sabía cómo...
Durante un montón de tiempo, (a lo mejor fue una o dos semanas, es
que antes los días duraban más que ahora), usé métodos
parecidos, sin saber porqué funcionaba... sólo sabía que
funcionaba y simplemente lo aceptaba. Después cayó en mis manos un
libro, esta vez en español, y me puse a leer la parte que explicaba
esto de las "matrices", antes no eran arrays... la verdad
es que lo leí como 20 veces o más... y parecía que nunca iba a
lograr asimilarlo, es que soy bastante duro de mollera y antes, que
era más joven, calculo que unas 14 veces más joven que ahora,
tenía la cabeza más dura. En aquella ocasión si que me hubiese
venido bien el programilla este de rascarme la cabeza...
Esto es lo que decía, el susodicho libro:
"El
lenguaje BASIC permite definir otro tipo de variables numéricas:
A(1), A(2)...A(N)
se llaman variables con índice y están formadas por un nombre de
variable, [...], seguido de un número natural entre paréntesis.
[...] el conjunto ordenado de estas variables se llama lista.
[...]"
Ahora que lo he
vuelto a leer, casi lo entiendo; pero para un pobre cateto
ignorante como yo, aquello sonaba a chino. Y si tu lo entiendes, me
alegro por ti...
Como te he comentado, el párrafo ese está sacado de un libro que
fue de los pocos que tuve, al menos en castellano, de los ingleses
sólo me interesaban los listados, que era lo único que
prácticamente traían. La cosa es, que a pesar de eso, hasta
aprendí un poco, a duras penas, sobre todo porque en aquellos
tiempos no tenía a quién preguntarle, ni quién me explicara
algunas de las muchas dudas que tenía... y si no tenía más dudas
era porque tampoco había profundizado demasiado. Pero lo que he
sacado en claro es que para aprender a programar hay que practicar,
practicar y seguir practicando... es como todo, cuanto más
practicas... o terminas por aburrirte o aprendes...
Vamos al tema, pero
sin teorías, las teorías se las dejo a los eruditos... ellos saben
cómo explicar "bien" las cosas... Y que conste que no
tengo nada en contra de las teorías, lo que ocurre, al menos a mi,
es que prefiero entender las cosas de forma práctica, que soy
"mu" torpe yo y si no lo veo funcionar, no me entero...
En el ejemplo ese
de las horas, nos vendría muy bien que pudiésemos usar otra
variable para la hora de nuestro "picor" y hacer algo
como:
HoradelPicor = HoradelPicor + 1, dónde "delPicor" sería
la hora en que nos rascamos la cabeza, así si "delPicor"
es 22, incrementar Hora22. Sí, lo reconozco, una vez intenté
hacerlo, creía que se podía hacer así:
delPicor = 22
HoradelPicor = HoradelPicor + 1
Pero el basic no hacía lo que yo quería, ni siquiera me daba
error, si en aquellos tiempos hubiese existido el Option Explicit,
me habría percatado de muchas cosas antes de tiempo...
Por suerte para
todos, existen los ARRAYS (o variables con índice) y realmente la
forma de hacerlo es casi como yo creía, lo único que cambiaba era
la forma... total, por un par de paréntesis...
Hora(delPicor) = Hora(delPicor) +1
Con esto le decimos al Basic: coge lo que hay guardado en la
variable que está en la posición delPicor del array Hora...
Vale, captado. Me
estoy lanzando y aún no te he presentado a los arrays.
Un Array es una
serie de variables que tienen el mismo nombre y para acceder a
cualquiera de esas variables, usamos un número (índice) para
indicar cual de esas variables es la que nos interesa... ¿Te has
enterado de que estoy hablando de variables o tengo que decirlo más
veces? Vale, admito que tampoco he sido demasiado claro, es que
realmente no es tan fácil de asimilar, pero en cuanto lo veas con
algunos ejemplos, seguro que lo "asimilas".
El basic, que es
"mu" listo, cuando ve esto:
Hora(delPicor), dice: "¿Cuanto vale lo que está dentro del
paréntesis?" (en caso de que sea una expresión en lugar de un
número o una variable, la evaluaría primero y usaría el
resultado), una vez que sabe cuanto vale lo que está dentro del
paréntesis... "ahora cojamos, del array, el contenido de la
variable que está en esa posición" (para el basic un array no
es más que una serie de variables que tienen el mismo nombre y lo
único que varía es "la dirección" en la que está
guardado el valor.
O sea que maneja los arrays de la misma forma que a las variables
simples, pero ampliando nuestros horizontes
"variabilísticos".
Ahora fíjate cómo podemos sumar las veces que nos hemos rascado la
cabeza a lo largo del día:
For i= 1 to 24
vecesDia = vecesDia + Hora(i)
Next
Cada vez que i cambia de valor, (en este caso tomando valores desde
1 hasta 24), el Basic usa una variable diferente del array Hora,
cuando i vale 1 está usando Hora(1) y cuando i vale 22, usa
Hora(22).
Lo de saber a que hora te has rascado más veces la cabeza te lo
dejo como ejercicio, sólo te diré que si haces esto:
masVeces = Horas(HoraMasVeces)
sabrás cuantas veces te has rascado a la hora HoraMasVeces...
Los elementos de un
array se comportan como variables normales, pudiendo usarlas en
expresiones y en cualquier otro sitio en el que podamos usar una
variable, realmente uno de los pocos sitios donde no puede usarse es
como índice de un bucle FOR, pero por lo demás, en cualquier
parte.
Imagínate que en la posición 22 del array Hora, es decir en
Hora(22) tenemos guardado un valor 15, al hacer esto:
Print Hora(22) * 10
mostraría 150, porque el VB ha sustituido Hora(22) por su valor y
lo ha multiplicado por 10, es como si internamente hubiese hecho:
Print 15*10.
Y tu dirás: esto mismo es lo que hace con las demás variables...
Efectivamente, ya que es una variable, especial, pero una variable
al fin y al cabo.
Sigamos
imaginando... suponte que quieres guardar en una variable a que
horas te pones a leer, cada día, las páginas del Guille y que
sabes que serán tres veces diarias, lo hay masoquistas... Podrías
hacer algo como esto:
Vez(1) = 20: Vez(2) = 22: Vez(3) = 23 '...(de nueve a diez vas a
cenar)
con lo cual tendrías un array con tres índices. El valor de cada
una de las variables del array "Vez", sería la hora en
que "guilleas" ... y si quieres incrementar los
"rascones" de la hora que está en la posición H, (que
puede ser 1, 2 ó 3):
Ahora = Vez(H) ' Si H vale 1, Ahora sería igual a 20
Hora(Ahora) = Hora(Ahora) + 1
Pero esto podrías hacerlo ahorrándotela variable Ahora, sería
así:
Hora(Vez(H)) = Hora(Vez(H)) + 1
¿Complicado? Pues si... que quieres que te diga... pero dejémoslo
estar...
Veamos cómo
podemos usar en nuestros programas este tipo especial de variables.
Antes yo las llamaba: "variables dimensionadas", entre
otras cosas porque era únicamente cuando necesitaba usar DIM, al
menos si iba a usar más de 10 "posiciones", aunque
también puede ser que lo leyera en algún sitio, no importa...
Para decirle al Basic que vas a usar tres variables en el array Vez,
hay que hacerlo de esta forma:
Dim Vez(3)
Ahora lo que necesitamos es un array para guardar los picores de las
24 horas del día:
Dim Hora(24)
Bueno, ya sabes
casi todo lo que tienes que saber de los arrays... ahora cómprate
un buen libro "teórico" y estúdiatelo... o léete lo que
dice el manual del Visual Basic... que también puede valer.
¿Aún sigues por
ahí...?
Bueno, ya que insistes, te explicaré algunas cosillas más...
Los arrays son
variables, algo especiales, pero variables al fin y al cabo.
Por tanto, podemos tener arrays numéricas, de carateres y en
definitiva de cualquier tipo que el Basic permita, lo único que
tenemos que hacer es indicárselo al reservar memoria:
Dim Vez(3) As Integer
Dim Amigos(1000) As String
Dim Salario(1000) As Currency
Cuando declaramos
un array, el Basic reserva memoria para cada una de las variables
que vamos a usar, o casi, ya que en realidad reserva una posición
más, no por nada en especial, sino porque empieza a contar desde
cero; por ejemplo en el array Vez, el índice más bajo que
podríamos usar es el 0 y el más alto el 3.
Esto ha sido así desde siempre... aunque en un intento de
"cambiar" las cosas, un listillo dijo: "El Basic
debería empezar a contar desde uno" y se sacaron una nueva
instrucción de la manga, desde mi punto de vista lo podrían haber
hecho mejor, pero como mis "preferencias" no las tuvieron
en cuenta... (tampoco tuve la oportunidad, la verdad sea dicha...),
el caso es que dijeron:
OPTION BASE 1 para que el índice menor de un array sea UNO y
OPTION BASE 0 para empezar por CERO, esta será la predeterminada.
Por tanto si usamos
este código:
Option Base 1
Dim Vez(3) As Integer
Crea un array con tres variables (del 1 al 3)
Más adelante, otro
listillo, (este fue un poco más inteligente), dijo: "Y si el
usuario pudiera decidir el valor menor y el mayor del índice de una
array"... "pues que bien", contestó otro...
Y así fue.
Imagínate que tu sólo te rascas la cabeza de 10 a 23, puedes
dimensionar así el array Hora:
Dim Hora(10 To 23) As Integer
De esta forma sólo "reservas" la memoria que necesitas...
Ya ves que todo son facilidades, aunque hay una cosa "muy"
importante que hay que tener en cuenta: Si pretendes acceder a una
posición del array que no está reservada, el Visual Basic te avisa
de que hay un error y detiene (termina) el programa. Esto es lo
único grave, pero si tu aplicación tiene información importante
pendiente de guardar, o se encontraba en medio de un proceso largo
de cálculo... realmente si que será grave... en otra ocasión
veremos cómo detectar los errores y poder "manejarlos"
para que no nos dejen en la "estacada"... Por tanto si
declaras un array que reserva tres posiciones, siempre consecutivas,
no podremos acceder a ninguna posición anterior o posterior a las
que tenemos declarada.
Pero... ¿y si
necesito más espacio? Lo único que tienes que hacer es
re-dimensionar el Array:
ReDim Vez(5) As Integer
¿Problemas? Si, que ya has perdido lo que antes había
almacenado...
Cuando yo empecé
con el Basic (¿otra batallita?, habrá que seguirle la
corriente...), no existía el ReDim. Pero si existía una forma de
conseguir esto mismo. El truco consistía en "borrar" el
array creado y volver a dimensionarlo... también recuerdo que me
dio muchos quebraderos de cabeza adaptar mi código (escrito en el
intérprete GwBasic... la GW ¿será Gates, William?) a un
compilador... eso de usar varias veces el DIM no lo digería bien...
pero eso es otra historia, que seguramente no contaré...
Para borrar un
array de la memoria, hay que usar ERASE seguido por el nombre del
array, por ejemplo: Erase Hora
Con esto conseguimos lo mismo que con ReDim Vez(5) As Integer:
Erase Vez
Redim Vez(5) As Integer
Pero, y si no
quisiéramos perder los valores anteriores...
Pues copia los datos en otro Array temporal, borras el primero, lo
vuelves a dimensionar con el nuevo número de elementos y a
continuación copias los datos del array temporal en el array que
acabas de redimensionar, después borras el array temporal, ya que
no lo necesitarás...
No, no es necesario tantas cosas, pero esto es lo que había que
hacer con el VB antes de la versión 3 y con el QuickBasic antes de
la versión 4, ahora sólo harás esto:
ReDim Preserve Vez(5)
Además cuando se ReDimensiona un array no hace falta volver a
especificar el tipo de dato, ya que tomará el mismo que se usó
inicialmente al declararlo.
La ventaja del
ReDim, con o sin Preserve, (podría haber hecho un chiste malo con
esto del Preserve, pero me abstengo...), es que puedes ampliar o
reducir el número de variables de un array... supón que después
de dimensionar Vez a cinco, lo piensas mejor y decides que con dos
veces es suficiente, pues nada, haces esto: Redim Preserve
Vez(2) y ya está. Lo importante es que sólo reserves la
memoria que vas a necesitar.
En la siguiente
entrega veremos más cosas de los arrays, así como algunas otras
instrucciones, pero no te voy a adelantar nada, no sea que después
no esté lo que tengo pensado y te mosquees.
Ahora vamos al
apartado de los ejercicios, que además del que te dije casi al
principio, te voy a poner otro más:
1.) Tienes un array con un número cualquiera de elementos, averigua
cual de las variables de ese array es la que tiene el valor mayor.
2.) La que tiene el valor menor y que no sea cero.
Como ves no te quiero que te
esfuerces demasiado.
Nos vemos.

