Академический Документы
Профессиональный Документы
Культура Документы
5
Contenido
Arrays
___________________________________________________________________________ 5.1.- Introduccin 5.2.- Utilidad de los arrays. 5.3.- Arrays en C++. 5.3.1.- Definicin de arrays. 5.4.- Definicin de tipos. Sentencia typedef. 5.5.- Operaciones con arrays. 5.3.1.- Acceso a elementos. 5.3.2.- Asignacin. 5.3.3.- Igualdad. 5.3.4.- Lectura y escritura. 5.3.5.- Recorrido de arrays. 5.5.- Arrays y subprogramas. 5.5.1.- Arrays como parmetros. 5.5.2.- Funciones y arrays. 5.6.- Ejemplos. Ejercicios ___________________________________________________________________________
5.1.- Introduccin.
En los temas anteriores se han estudiado los diferentes tipos de datos simples de C++, usados para representar valores simples como enteros, reales o caracteres. Sin embargo, en muchas situaciones se precisa procesar una coleccin de valores que estn relacionados entre s, como por ejemplo una lista de calificaciones, una tabla de temperaturas, etc. El procesamiento de tales conjuntos de datos utilizando tipos simples puede ser extremadamente complejo y tedioso, y por ello la mayora de los lenguajes de programacin incluyen mecanismos sintcticos para manipular agrupaciones de datos, son las llamadas estructuras de datos. Definicin: Una estructura de datos es una coleccin de datos que pueden ser caracterizados ___________________________________________________________________________
Elementos de Programacin Arrays Pg 1
por su organizacin y por las operaciones que se definan en ella. En una estructura de datos podremos hacer referencia tanto a la coleccin de elementos completa como a cada uno de sus componentes de forma individual. La estructura de datos ms bsica soportada por los lenguajes es el array.
Esto implica que necesitaramos 20 variables para retener los valores de las ventas, una por cada agente: ventas1, ventas2, ...., ventas20. Un posible programa sera:
#include <stdlib.h> #include <iostream.h> const double PORCION = 2.0/3.0; void main () { double ventas1, ventas2,..., ventas20; double suma, umbral; suma = 0.0; cout << "Introduzca las ventas del agente 1: "; cin >> ventas1; suma += ventas1; cout << "Introduzca las ventas del agente 2: "; cin >> ventas2;
___________________________________________________________________________
Elementos de Programacin Arrays Pg 2
suma += ventas2; ...... cout << "Introduzca las ventas del agente 20: "; cin >> ventas20; suma += ventas20; umbral = PORCION * (suma / 20.0); cout << "Agentes que superan el umbral y sus ventas" << endl; if (ventas1 > umbral) cout << 1 << ": " << ventas1 << endl; if (ventas2 > umbral) cout << 1 << ": " << ventas1 << endl; ....... if (ventas20 > umbral) cout << 20 << ": " << ventas20 << endl; system("pause"); } // Espera que se pulse una tecla para acabar
La escritura de este programa es, como se ve, bastante tediosa. El problema se agravara ms si en lugar de 20 hubiera 200 agentes de ventas. Necesitaramos 200 variables, 200 lecturas de datos y 200 comprobaciones del umbral. Una mejor solucin consiste en agrupar estas variables de ventas en una estructura de datos array. Un array se puede visualizar como una coleccin de cajas que representan variables de un mismo tipo de datos, tal y como se ilustra en la siguiente figura. A este tipo de array se le suele denominar array unidimensional o vector. As:
double ventas [20];
.......
0 1 2 i
.......
18 19
Para hacer referencia a una caja o componente en particular, usaremos el nombre o identificador del array seguido por un nmero (ndice) entre corchetes, que indicar su posicin dentro del array. En este caso dicho ndice sera funcin del nmero de identificacin del correspondiente agente de ventas.
ventas [i]
Realmente lo que va entre corchetes al referirse a la posicin de un componente de un array, puede ser cualquier expresin que al evaluarse d como resultado un valor numrico entero positivo. ___________________________________________________________________________
Elementos de Programacin Arrays Pg 3
De esta forma podremos tratar a los agentes de ventas de forma repetitiva, y nuestro programa podra escribirse de la siguiente manera:
#include <stdlib.h> #include <iostream.h> const double PORCION = 2.0/3.0; void main () { double ventas [20]; double suma, umbral; int i; suma = 0.0; for (i = 0; i < 20; i++) { cout << "Introduzca las ventas del agente " << i + 1 << ": "; cin >> ventas [i]; suma += ventas [i]; } umbral = PORCION * (suma / 20.0); cout << "Agentes que superan el umbral y sus ventas" << endl; for (i = 0; i < 20; i++) { if (ventas [i] > umbral) cout << i + 1 << ": " << ventas [i] << endl; } system("pause"); // Espera que se pulse una tecla para acabar }
Si es posible que el nmero de agentes vaya a variar en algn momento de la vida de la empresa, es preferible definir una constante global (const int NAGENTES = 20), y sta se pone en los lugares del algoritmo en los que antes hemos puesto 20. Con esto, al cambiar el nmero de agentes, slo hay que reflejarlo en la declaracin de la constante y no en todos los sitios en los que aparezca la cantidad 20, como ocurrir en el programa anterior. Siempre lo haremos as a partir de ahora. La versin final de nuestro algoritmo quedara entonces como:
#include <stdlib.h> #include <iostream.h> const int NAGENTES = 20; const double PORCION = 2.0/3.0; void main () { double ventas [NAGENTES]; double suma, umbral; int i; suma = 0.0; for (i = 0; i < NAGENTES; i++) { cout << "Introduzca las ventas del agente " << i + 1 << ": ";
___________________________________________________________________________
Elementos de Programacin Arrays Pg 4
cin >> ventas [i]; suma += ventas [i]; } umbral = PORCION * (suma / double (NAGENTES)); cout << "Agentes que superan el umbral y sus ventas" << endl; for (i = 0; i < NAGENTES; i++) { if (ventas [i] > umbral) cout << i + 1 << ": " << ventas [i] << endl; } system("pause"); // Espera que se pulse una tecla para acabar }
Ntese como en el clculo del umbral utilizamos una promocin explcita (casting) del tipo de la constante NAGENTES para convertirla de int a double, aunque realmente esta conversin de tipos explcita no es necesaria ya que C++ promociona automticamente a double todos los datos de la expresin aritmtica anterior.
Una variable de array se puede ver como un conjunto de variables del mismo tipo a las que denominamos con un nombre comn. Algunas caractersticas importantes de los arrays en C++ son: Los elementos del array se almacenan consecutivamente en memoria. El nombre del array especifica la direccin en memoria del primer elemento del mismo. El nombre del array es una direccin constante, es decir no puede modificarse su valor. Como tipo estructurado, no esta permitida la lectura y escritura directa sobre dispositivos de E/S estndares. Este tipo de operaciones debe realizarse elemento a elemento. Todas las operaciones disponibles sobre los tipos asociados a las componentes, pueden usarse sobre ellos.
___________________________________________________________________________
Elementos de Programacin Arrays Pg 5
Un tipo array estar formado por todos los posibles arrays con componentes de tipo base T y con un determinado tipo de ndice I (todos los arrays del mismo tipo poseen la misma cantidad de elementos) que se puedan formar.
En caso de definir varias variables de array con el mismo tipo base se har de la forma: tipo nombre1 [dimensin1], nombre2 [dimension2], ..., nombren [dimensinn]; Ejemplos:
int vector [10]; char frase [80]; bool flags [5], logicos [10]; // Array de 10 enteros // Array de 80 caracteres // Un array de 5 lgicos y // otro de 10 lgicos
Aunque lo ms adecuado, tal como se ha comentado en el programa de ejemplo del apartado anterior, es usar constantes globales para definir la dimensin de los arrays.
const const const const int int int int MAXVECTOR = 10; MAXFRASE = 80; MAXFLAGS = 5; MAXLOGICOS = 10; // Array de 10 enteros // Array de 80 caracteres // Un array de 5 lgicos y // otro de 10 lgicos.
int vector [MAXVECTOR]; char frase [MAXFRASE]; bool flags [MAXFLAGS], logicos [MAXLOGICOS];
En BNF:
<array> ::= [<cualificador>] [<almacenamiento>] <nombre_tipo> <identificador> "[" <dimension> "]";
___________________________________________________________________________
Elementos de Programacin Arrays Pg 6
donde i es un nmero natural, denominado " ", que representa el nmero de orden del componente que queremos acceder. El primer componente lo denotaremos con el valor ndice 0, el segundo con el valor 1, el i-simo con el valor i-1, etc. El ltimo elemento del array se podr seleccionar mediante "nombre_array [dimensin - 1]". Ejemplo:
const int MAXA = 10; int a [MAXA];
En el ejemplo "a" ser un array que contiene 10 elementos de tipo entero, cada uno de ellos con un ndice asociado (0 a 9). Grficamente, por ejemplo:
componentes ndices
As:
a [4] a [7] a [1]
8
0
-4
1
0
2
3
3
5
4
60 -3
5 6
4
7
5
8
8
9
Hay que sealar que el array "a" comprende toda la estructura, mientras que cada uno de los elementos pertenece al tipo int ( en este caso el tipo base ). En resumen, se puede seleccionar cada uno de los elementos del array, indicando la posicin que ocupa dentro del mismo, siguiendo con el ejemplo de la figura, para seleccionar la variable entera que es el tercer componente del array (el de valor 0), basta con que al nombre del array le siga la posicin que ocupa dicho componente dentro del array entre corchetes empezando por 0, es decir en este caso, "a [2]".
En BNF:
<definicin_tipo> ::= typedef <nombre_tipo> <identificador>;
___________________________________________________________________________
Elementos de Programacin Arrays Pg 7
El objetivo fundamental de esta sentencia es mejorar la claridad del cdigo fuente asociando nombres simblicos a tipos de datos definidos por el programador. Los pasos a seguir para definir un nuevo nombre de tipo son los siguientes: 1. Escribir la sentencia de definicin como si una variable del tipo deseado se estuviera declarando. 2. En el lugar donde aparece normalmente el nombre de la variable declarada, poner el nuevo nombre de tipo. 3. Delante de todo esto colocar la palabra typedef. 4. Posteriormente utilizar el nombre definido como el de un tipo de datos para definir nuevas variables. Ejemplo: Definir la variable a como perteneciente a un tipo array de 10 enteros:
1. 2. 3. 4. int a [10]; int Tarray [10]; typedef int Tarray [10]; Tarray a;
Segn esto, en el caso de definicin de tipos array la sintaxis concreta sera entonces:
typedef tipo_base nombre_nuevo_tipo [dimensin];
Ejemplos:
typedef int Tvector [4]; typedef char Ttexto [10]; typedef unsigned int Tlista [7];
Nota: Slo se puede definir un nico tipo en cada sentencia typedef. Importante: Por cuestiones de mbito es recomendable definir los tipos mediante la sentencia typedef de forma global fuera de los subprogramas, al principio del texto del programa. De esta forma sern visibles tanto para definir parmetros reales como formales.
Las operaciones que se suelen realizar con arrays durante el proceso de resolucin de un problema son: Acceso a los elementos. Asignacin. Igualdad. Lectura/escritura. Recorrido (acceso secuencial).
En general, las operaciones con arrays implican el procesamiento o tratamiento de los elementos individuales del vector.
Los ndices comienzan siempre por 0, es decir el primer elemento de un array tiene ndice 0. Es importante comprender que el valor que representa el acceso a una de las componentes del array, pertenece al tipo base del array, pudindose utilizar dicha referencia (o de cualquier otro componente del array) en cualquier situacin en que lo pueda ser una variable del mismo tipo base. Como por ejemplo a la izquierda de una sentencia de asignacin, dentro de una expresin, como parmetro de un subprograma, etc. Todas las operaciones disponibles sobre los tipos de los componentes, pueden usarse sobre ellos sin ninguna restriccin. Ejemplo:
... typedef unsigned int Tarray20 [20]; ... void unaFuncion (unsigned int a) { ... } ... Tarray20 nuevoArray; unsigned int i; nuevoArray [19] = 5; i = nuevoArray [0] + 2; // Tipo array de 20 naturales
// Variable de array
// Asigna el valor 5 a la ltima // componente del vector nuevoArray. // Asigna el valor del primer // componente del array ms dos a la // variable i
___________________________________________________________________________
Elementos de Programacin Arrays Pg 9
// Pasa como parmetro a la funcin // unaFuncion el valor contenido en el // elemento sexto del array, el que // tiene como valor indice 5
...
Otro aspecto importante del ndice asociado a las componentes de un array es que indica un orden dentro de la estructura, as podemos acceder a la primera componente, a la segunda componente y as sucesivamente. Esto implica que el ndice es calculable, facilitando el tratamiento de las componentes del array. Es decir los valores de ndice pueden ser cualquier expresin que de cmo resultado un nmero natural inferior a la dimensin del array. Ejemplo:
typedef unsigned int Tarray20 [20]; ... Tarray20 nuevoArray; int i; i = 6; nuevoArray [i + 1] = 2; // Asigna el valor 2 a la octava componente // del array, aquella con ndice 7
C++ no produce ningn error en indexaciones del array fuera de rango, es decir valores de ndice que excedan su dimensin., por lo que hay que extremar la precaucin a la hora de seleccionar elementos de un array. Ejemplo:
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 5; typedef unsigned int Tarray [MAXARRAY]; void main () { Tarray array; int indice; for (indice = 0; indice < MAXARRAY; indice++) array [indice] = indice * 10; for (indice = 0; indice <= MAXARRAY; indice++) cout << indice << " : " << array [indice] << endl; system("pause"); } // Espera que se pulse una tecla para acabar
Ntese como existe un error en el segundo bucle, ya que la variable de control llega a tomar el valor MAXARRAY (5 en este caso) con lo que se intenta seleccionar un elemento que no existe en el array. Sin embargo el compilador no detectar ningn error, y al ejecutar el programa el resultado ___________________________________________________________________________
Elementos de Programacin Arrays Pg 10
Obsrvese como al no existir en el array un elemento con ndice 5, lo que aparece en pantalla es cualquier cosa que haya en memoria a continuacin del array. De hecho, en diferentes mquinas e incluso en distintas ejecuciones del programa sobre la misma mquina, el valor para el elemento con ndice 5 podr ser distinto.
Como se ha visto anteriormente, se puede asignar valor a un array, asignando valores a sus componentes individuales. Vamos a intentar asignar el valor de una variable array a otro array de forma directa como en el siguiente ejemplo.
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 3; typedef int Tarray [MAXARRAY]; void main () { Tarray a, b; b[0] = 3; b[1] = 2; b[2] = 1; a = b; } // Asignacin completa de arrays. INCORRECTO.
Observaremos que el compilador detecta el siguiente error: "warning: ANSI C++ forbids assignment of arrays". Nos est avisando de que no se permite la asignacin completa de arrays. Por tanto tendremos que asignar los valores elemento a elemento, ayudndonos de una estructura iterativa, tal como se presenta a continuacin:
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 3; typedef int Tarray [MAXARRAY]; void main () { Tarray a, b; int i;
___________________________________________________________________________
Elementos de Programacin Arrays Pg 11
b[0] = 3; b[1] = 2; b[2] = 1; for (i = 0; i < MAXARRAY; i++) { // Asignacin completa por componentes. CORRECTO. a [i] = b[i]; } }
Por otro lado, en C++ puede inicializarse el valor de todo un array en la declaracin del mismo de la siguiente forma:
tipo nombre_array = {valor_1, valor_2, ..., valor_N};
De esta forma es posible definir arrays constantes, aadiendo el modificador "const" de la siguiente forma:
const tipo_array nombre_array = {valor_1, valor_2, ... , valor_N};
Ejemplo:
const int MAXCAD = 10; typedef char cadena [MAXCAD]; const cadena vocales = {'A','a','E','e','I','i','O','o','U','u'};
En este caso el array vocales no podr ser modificado. Importante: La inicializacin de arrays de esta forma solo es posible en su declaracin, no se puede utilizar como parte de una asignacin en el cdigo.
El mes 1 tiene 31 dias. El mes 2 tiene 28 dias. El mes 3 tiene 31 dias. El mes 4 tiene 30 dias. El mes 5 tiene 31 dias. El mes 6 tiene 30 dias. El mes 7 tiene 31 dias. El mes 8 tiene 31 dias. El mes 9 tiene 30 dias. El mes 10 tiene 31 dias. El mes 11 tiene 30 dias. El mes 12 tiene 31 dias. Presione una tecla para continuar . . .
De todas formas, hay que tener en cuenta que este programa no es correcto, fallar cada cuatro aos, ya que no contempla los aos bisiestos. Si en el programa intentamos cambiar el valor de algn componente del array, el compilador assignment of read-only location", ya que se trata de un array constante que no puede cambiar de valor. Por otro lado, que ocurrira si el tamao de la lista de valores para inicializar el array es
... const int MAXMESES = 12; typedef unsigned int Tdias [MAXMESES]; ... const Tdias dias = {31,28,31,30,31,30,31,31,30,31,30,31,99}; int indice; ...
En este caso, la lista de inicializacin tiene ms valores que la dimensin del array y el compilador nos dar el siguiente error: "excess elements in aggregate initializer"
#include <stdlib.h> #include <iostream.h> const int MAXMESES = 12; typedef unsigned int Tdias [MAXMESES]; void main () { const Tdias dias = {31,28,31,30,31,30,31,31,30,31}; int indice; for (indice = 0; indice < MAXMESES; indice++) { cout << "El mes " << indice + 1 << " tiene " << dias [indice] << " dias." << endl; } system("pause"); // Espera que se pulse una tecla para acabar }
En este otro caso, la lista de valores es menor que la dimensin del array, sin embargo el compilador no nos dar ningn error y el programa se ejecutar, dando el siguiente resultado: ___________________________________________________________________________
Elementos de Programacin Arrays Pg 13
El mes 1 tiene 31 dias. El mes 2 tiene 28 dias. El mes 3 tiene 31 dias. El mes 4 tiene 30 dias. El mes 5 tiene 31 dias. El mes 6 tiene 30 dias. El mes 7 tiene 31 dias. El mes 8 tiene 31 dias. El mes 9 tiene 30 dias. El mes 10 tiene 31 dias. El mes 11 tiene 0 dias. El mes 12 tiene 0 dias. Presione una tecla para continuar . . .
Observamos que C++ inicializa por defecto a cero los valores restantes del array. Veamos como lo hace para distintos tipos de datos, y en este caso sin usar el modificador "const":
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 5; void main () { int i; int pru [MAXARRAY] = {1,2}; float pru1 [MAXARRAY] = {1.0,2.0}; bool pru2 [MAXARRAY] = {true, false}; char pru3 [MAXARRAY] = {'a', 'b'}; for (i = 0; i < MAXARRAY; i++) { cout << i << " pru " << pru[i] << " pru1 " << pru1[i] << " pru2 " << pru2[i] << " pru3 " << pru3[i] << endl; } system("pause"); // Espera que se pulse una tecla para acabar }
Por ltimo, insistir en que al no verificar C++ los ndices fuera de rango hay que extremar las precauciones a la hora de manipularlos y especialmente cuando se realizan asignaciones. Ejemplo:
#include <stdlib.h>
___________________________________________________________________________
Elementos de Programacin Arrays Pg 14
#include <iostream.h> const int MAXARRAY = 3; typedef unsigned int Tarray [MAXARRAY]; void main () { Tarray a1, a2; int i; for (i = 0; i <= MAXARRAY + 1; i++) // Error: i < MAXRRAY { a1 [i] = i * 10; a2 [i] = i * 10; } for (i = 0; i < MAXARRAY; i++) cout << i << " : " << a1 [i] << " " << a2 [i] << endl; system("pause"); } // Espera que se pulse una tecla para acabar
Obsrvese el error cometido en la condicin de control del bucle "for", en el que se llega a dar el valor 3 a la variable de condicin del bucle i, y se ejecuta el cuerpo del bucle asignando valores a los componentes inexistentes a1[3] y a2[3]. El compilador no detectar ningn error y ejecutar el programa. El resultado de la ejecucin del mismo usando el compilador Dev C++ es el siguiente:
0 : 40 0 1 : 10 10 2 : 20 20 Presione una tecla para continuar . . .
Obsrvese como a1 [0] que se inicializ con el valor 0 tiene el valor 40, ello se debe a que dicho valor ha sido machacado o bien por la asignacin a1 [3] = 3 * 10 o bien por la asignacin a2 [3] = 3 * 10, produciendo adems un valor extrao. En otra mquina, otro compilador u otro entorno el efecto errneo producido puede ser diferente.
5.5.3.- Igualdad.
Vamos a intentar verificar la igualdad de dos arrays completos de forma directa mediante el siguiente ejemplo.
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 3; typedef int Tarray [MAXARRAY]; void main () { Tarray a, b; a[0] = 3; a[1] = 2;
___________________________________________________________________________
Elementos de Programacin Arrays Pg 15
a[2] = 1; b[0] = 3; b[1] = 2; b[2] = 1; if (a == b) cout << "Iguales" << endl; else cout << "Distintos" << endl; system("pause"); } // Espera que se pulse una tecla para acabar
Como vemos, aunque ambos arrays son del mismo tipo, tamao y tienen el mismo contenido el resultado de la comparacin aparentemente es errneo. Ello es debido a que en el lenguaje C++ hay una relacin muy estrecha entre arrays y direcciones de memoria, que podramos resumir diciendo que el nombre de una variable de array denota la direccin de memoria de su primer elemento.
int a [10]; => a == &a [0]
Y claro, las direcciones de memoria en donde estn situados los dos arrays del ejemplo son distintas. Por eso la verificacin de igualdad no se cumple, porque en C++ se comparan las direcciones de memoria en las que se encuentran los arrays, no sus contenidos. La nica forma para poder entonces verificar la igualdad de dos arrays es realizando una funcin lgica en la que mediante una estructura iterativa se comparen todos y cada uno de los elementos de ambos arrays que tengan el mismo valor de ndice.
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 3; typedef int Tarray [MAXARRAY]; bool iguales (Tarray a, Tarray b) { int i; bool resultado; resultado = true; i = 0; while ((i < MAXARRAY) && resultado) { resultado = a [i] == b[i]; i++; } return resultado; } void main ()
___________________________________________________________________________
Elementos de Programacin Arrays Pg 16
{ Tarray a, b; b[0] = 3; b[1] = 2; b[2] = 1; a[0] = 3; a[1] = 2; a[2] = 1; if (iguales (a, b)) cout << "Iguales" << endl; else cout << "Distintos" << endl; system("pause"); a[0] = 1; a[1] = 2; a[2] = 3; if (iguales (a, b)) cout << "Iguales" << endl; else cout << "Distintos" << endl; system("pause"); } // Espera que se pulse una tecla para acabar // Espera que se pulse una tecla para seguir
Leer un array.
for (i = 0; i < MAXIMO; i++) cin >> x[i];
___________________________________________________________________________
Elementos de Programacin Arrays Pg 18
igual forma podremos usar un elemento de un array para recoger el resultado de una funcin, siempre que el tipo base del array coincida o sea compatible con el de la funcin. Veamos a continuacin el paso completo de arrays con subprogramas.
___________________________________________________________________________
Elementos de Programacin Arrays Pg 19
Sin embargo, aunque en el ejemplo anterior no usemos el cualificador & de paso de parmetros por referencia en la definicin de los parmetros formales, ste es el mecanismo que sigue C++ a la hora de pasar arrays como parmetros. Vemoslo el siguiente ejemplo:
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 3; typedef int Tarray [MAXARRAY]; void cambiar (Tarray x) { int j; for (j = 0; j < MAXARRAY; j++) x[j] *= 10; } void imprimir (Tarray m) { int j; for (j = 0; j < MAXARRAY; j++) { cout << "El elemento " << j << " tiene el valor : " << m[j] << endl; } } void main () { Tarray a = {1, 2, 3}; cout << "Antes de llamar a cambiar" << endl; imprimir (a); cambiar (a); cout << "Despues de llamar a cambiar" << endl; imprimir (a); system("pause"); } // Espera que se pulse una tecla para acabar
Como vemos, el subprograma ha modificado los parmetros reales que se le han pasado. Ello es debido a la relacin existente entre los arrays y las direcciones de memoria que ya se coment anteriormente. ___________________________________________________________________________
Elementos de Programacin Arrays Pg 20
Este hecho repercute en el paso de parmetros cuando estos son arrays. En efecto, en C++ no se puede pasar un array por valor, ya que C++ trasmite siempre por referencia las variables de array, y al pasar su nombre no realiza una copia del valor sino lo que hace realmente es pasar su direccin (una referencia al parmetro real). As, en la instruccin que invoca a una funcin, se escribe siempre el nombre de la variable sin mas y en la cabecera de la funcin invocada se indica el tipo y nombre del correspondiente
Por todo ello es necesario extremar las precauciones a la hora de trabajar con arrays y subprogramas. Finalmente podemos generalizar aun ms el diseo de subprogramas con arrays si en vez de utilizar la constante global que indica la dimensin del array dentro del subprograma usamos el operador sizeof. Sintaxis: sizeof (nombre_tipo) En BNF:
<operador_sizeof> ::= sizeof ( <nombre_tipo> )
En donde nombre_tipo es el nombre de un tipo predefinido o un tipo definido mediante la sentencia typedef, sea simple o estructurado. Este operador devuelve el nmero de bytes que ocupa una variable del tipo que se le indica en un compilador y maquina concreto. Ejemplo:
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 5; typedef int Tentero; typedef int Tarray [MAXARRAY]; void main () { cout << cout << cout << cout << cout << cout << cout << cout << cout << cout << }
"char "bool "int "Tentero "short int "long int "unsigned int "float "double "Tarray
: : : : : : : : : :
" " " " " " " " " "
<< << << << << << << << << <<
sizeof sizeof sizeof sizeof sizeof sizeof sizeof sizeof sizeof sizeof
(char) << endl; (bool) << endl; (int) << endl; (Tentero) << endl; (short int) << endl; (long int) << endl; (long int) << endl; (float) << endl; (double) << endl; (Tarray) << endl;
system("pause");
___________________________________________________________________________
Elementos de Programacin Arrays Pg 21
La utilidad de este operador a la hora de disear subprogramas con arrays es que nos evita el tener que usar el nmero o constante que define la dimensin del array, pudiendo calcularlo dinmicamente; aunque realmente este clculo es resuelto en tiempo de compilacin y por tanto no sobrecarga la ejecucin del subprograma. Esto permite construir subprogramas ms
La forma de usarlo es simplemente sustituir la constante que indica la dimensin del array por la siguiente expresin constante: sizeof (tipo_array) / sizeof (tipo_base) Como sizeof(tipo_array) nos da como resultado el nmero de bytes que ocupa una variable del tipo_array, si dividimos ese valor por el nmero de bytes que ocupa cada componente (los cuales son de tipo_base) obtendremos la dimensin del array. Veamos el ejemplo anterior de uso de subprogramas aplicando los operadores sizeof dentro de los mismos.
#include <stdlib.h> #include <iostream.h> const int MAXARRAY = 3; typedef int Tarray [MAXARRAY]; void cambiar (Tarray x) { int j; for (j = 0; j < sizeof(Tarray) / sizeof(int); j++) x[j] *= 10; } void imprimir (Tarray m) { int j; for (j = 0; j < sizeof(Tarray) / sizeof(int); j++) { cout << "El elemento " << j << " tiene el valor : " << m[j] << endl; } }
___________________________________________________________________________
Elementos de Programacin Arrays Pg 22
void main () { Tarray a = {1, 2, 3}; cout << "Antes de llamar a cambiar" << endl; imprimir (a); cambiar (a); cout << "Despues de llamar a cambiar" << endl; imprimir (a); system("pause"); } // Espera que se pulse una tecla para acabar
___________________________________________________________________________
Elementos de Programacin Arrays Pg 23
Al compilarlo se produce el siguiente error de compilacin: "'leeVector' declared as function returning an array". Claramente C++ no permite devolver el valor de un array. Por tanto no se deben usar arrays como resultado de funciones. Si necesitamos devolver un array, usaremos entonces un procedimiento con un parmetro pasado por referencia para el array (de hecho como vimos anteriormente los parmetros de array siempre se pasan por referencia), con lo que el programa anterior deberamos escribirlo de la siguiente manera:
#include <stdlib.h> #include <iostream.h> const int MAXIMO = 10; typedef int Tvector [MAXIMO]; void leeVector (Tvector &x) { int i; for (i = 0; i < sizeof(Tvector) / sizeof(int); i++) { cout << "Introduzca x[" << i << "] = "; cin >> x[i]; } return x; } void escribeVector (Tvector x) { int i; for (i = 0; i < sizeof(Tvector) / sizeof(int); i++) cout << "x[" << i << "] = " << x [i] << endl; } void main () { Tvector vector; leeVector(vector); escribeVector (vector); system("pause"); } // Espera que se pulse una tecla para acabar
___________________________________________________________________________
Elementos de Programacin Arrays Pg 24
5.7.- Ejemplos.
Para terminar veamos un programa ejemplo completo sobre el manejo de arrays. Un palndromo es una frase que (atendiendo slo a sus letras e ignorando los espacios, acentos, signos de puntuacin y tipo de letra, mayscula o minscula) expresa lo mismo leda de izquierda a derecha que de derecha a izquierda. Por ejemplo: "dabale arroz a la zorra el abad" Se necesita un programa que lea una frase de no ms de 100 letras, terminada en un punto, y que determine si es o no un palndromo. Para ello usaremos un array con tipo base char.
//-----------------------------------------------------------------------// Autor: // Fecha: Versin: 1.0 //-----------------------------------------------------------------------// Programa ejemplo para la determinacin de si una frase es // un palndromo. //-----------------------------------------------------------------------#include <stdlib.h> #include <iostream.h> const char TERMINADOR = '.'; const int MAXIMO = 100; typedef char Tfrase [MAXIMO]; char aMayuscula (char c) { if ((c >= 'a') && (c <= 'z')) return char (int (c) - int('a') + int('A')); else return c; } void main () { Tfrase int char
frase; i, j; car;
cout << "Escriba la frase, terminada por " << TERMINADOR << " : "; i = 0; do { cin >> car; // Se filtran todos los caracteres recogidos que no sean letras if (((car>='A') && (car<='Z')) || ((car>='a') && (car<='z'))) { frase [i] = aMayuscula (car); i++; } } while ((car != TERMINADOR) && (i < MAXIMO)); i--; j = 0; while ((j < i) && (frase [j] == frase [i])) {
___________________________________________________________________________
Elementos de Programacin Arrays Pg 25
j++; i--; } if (j >= i) cout << "Es palindromo" << endl; else cout << "No es palindromo" << endl; system("pause"); } // Espera que se pulse una tecla para acabar
Obsrvese la utilizacin de los operadores de conversin de tipo (casting) para calcular la letra mayscula correspondiente a una minscula dentro de la funcin aMayuscula. La expresin "char (int (c) - int('a') + int('A'))" es equivalente a la expresin en pseudolenguaje "CHR (ORD (c) - ORD ('a') + ORD ('A')".
Veamos otro ejemplo. Realizar un programa en C++ que procese mediante subprogramas un array de hasta 100 nmeros reales realizando las siguientes tareas: a) b) c) d) e) f) g) Lectura del array. Impresin en pantalla del array introducido. Determinacin del nmero menor del array. Clculo de la suma de los elementos del array. Clculo de la media de los valores del array. Clculo de la varianza de los valores del array. Clculo de la desviacin tpica de los valores del array.
//-----------------------------------------------------------------------// Autor: // Fecha: Versin: 1.0 //-----------------------------------------------------------------------// Programa ejemplo de procesamiento de un vector de reales //-----------------------------------------------------------------------#include <stdlib.h> #include <iostream.h> #include <math.h> const int MAXIMO = 100; typedef double Tvector [MAXIMO]; void leeVector (Tvector &x, int &tam) { int i; cout << "Introduzca el tamao del vector a procesar (maximo " << sizeof(Tvector) / sizeof(double) << "): "; cin >> tam; if (tam < 0) tam = 0; else if (tam > sizeof(Tvector) / sizeof(double)) tam = sizeof(Tvector) / sizeof(double); for (i = 0; i < tam; i++) {
___________________________________________________________________________
Elementos de Programacin Arrays Pg 26
cout << "Introduzca x[" << i << "] = "; cin >> x[i]; } } void escribeVector (Tvector x, int tam) { int i; for (i = 0; i < tam; i++) cout << "x[" << i << "] = " << x [i] << endl; } double menorVector (Tvector x, int tam) { double menor; int i; menor = x [0]; for (i = 1; i < tam; i++) menor = (menor > x [i]) ? x [i] : menor; return menor; } double sumaVector (Tvector x, int tam) { double suma; int i; suma = 0.0; for (i = 0; i < tam; i++) suma += x [i]; return suma; } double mediaVector (Tvector x, int tam) { return sumaVector (x, tam) / tam; } double varianzaVector (Tvector x, int tam) { double suma, media; int i; suma = 0.0; media = mediaVector (x, tam); for (i = 0; i < tam; i++) suma += pow (x [i] - media, 2.0); return suma / tam; } double desviacionVector (Tvector x, int tam) { return sqrt ((varianzaVector (x, tam) * tam) / (tam - 1)); } void main () { Tvector int
vector; tamano;
___________________________________________________________________________
Elementos de Programacin Arrays Pg 27
cout << "Introduzca las componentes del vector" << endl; leeVector (vector, tamano); cout << "Vector introducido" << endl; escribeVector (vector, tamano); cout cout cout cout cout } << << << << << "Valor menor = " << menorVector (vector, tamano) << endl; "Sumatorio = " << sumaVector (vector, tamano) << endl; "Media = " << mediaVector (vector, tamano) << endl; "Varianza = " << varianzaVector (vector, tamano) << endl; "Desviacion = " << desviacionVector (vector, tamano) << endl; // Espera que se pulse una tecla para acabar
system("pause");
___________________________________________________________________________
Elementos de Programacin Arrays Pg 28
Ejercicios.
1.Disea un programa C++ que solicite dos vectores por teclado y calcule su producto escalar y su producto vectorial. Escribe un programa C++ que lea una sucesin de 10 nmeros naturales, encuentre el valor mximo y lo imprima junto con el nmero de veces que aparece, y las posiciones en que esto ocurre. El proceso se repite con el resto de la sucesin hasta que no quede ningn elemento por tratar. Ejemplo de entrada: 7 10 143 10 52 143 72 10 143 7 Salida generada: 143 aparece 3 veces, en posiciones 3 6 9. ... 7 aparece 2 veces, en posiciones 1 10 3.Disea un programa C++ para realizar la conversin de nmeros en base decimal entre 0 y 32000 a base hexadecimal. Para ello el algoritmo tendr como: Datos de entrada: Un nmero entero positivo entre 0 y 32000 cualquiera dado por el usuario. El programa deber verificar que el numero entrado cumple esas condiciones. Datos de salida: Impresin en pantalla de un array de caracteres que contenga el equivalente en base hexadecimal del numero entrado. Este array deber estar formado por un mximo de cuatro elementos (dgitos) que pueden ser cifras entre 0 y 9 y letras entre A y F.
2.-
4.-
Disea un programa C++ que lea por teclado las coordenadas en el plano de dos vectores y calcule el ngulo en grados que forman esos dos vectores. Dadas las siguientes definiciones de tipo: typedef char Tvector [N]; typedef char Tvectorg [2 * N]; a) Disea una funcin que, dados dos vectores ordenados del tipo Tvector como parmetros, devuelva otro vector ordenado de tipo Tvectorg que sea la mezcla de ambos. b) Disea una funcin lgica que dados dos vectores del tipo Tvector, devuelva true si son iguales y false en otro caso. Para este caso supondremos que dos vectores son iguales si contienen los mismos elementos y en el mismo orden relativo, suponiendo que el primer elemento sigue al ltimo. Por ejemplo, si la entrada fuera: ['A', 'C', 'D', 'F', 'E'] ['D', 'F', 'E', 'A', 'C'] la funcin devolvera true. Supn, adems, que cada carcter aparece a lo sumo una vez.
5.-
___________________________________________________________________________
Elementos de Programacin Arrays Pg 29
c) La moda de un array de caracteres es el carcter del array que se repite ms frecuentemente. Si varios caracteres se repiten con la misma frecuencia mxima, entonces no hay moda. Escribe un procedimiento que acepte un vector de tipo Tvector y devuelva la moda, o una indicacin de que la moda no existe. 6.Para operar con nmeros naturales de tamao grande se puede utilizar un array cuyas componentes sean dgitos decimales (entre 0 y 9, ambos inclusive). Elaborar un programa en C++ para sumar nmeros naturales de hasta 40 cifras por el procedimiento anterior. Ejemplo: Nmero 1: 394774123 Nmero 2: 46957 Resultado: 394821080 Los nmeros a sumar no contienen decimales. 7.Dado un polinomio de grado n, p(x) = pnxn + pn-1xn-1 + ... + p1x + p0, podemos representarlo mediante un array de sus coeficientes (pn, pn-1, ..., p1, p0). Disea un programa C++ que lea dos polinomios, los almacene en sendos arrays y calcule la suma y el producto de ambos. 8.Dado un array f de enteros con dimensin N, diremos que un elemento es redundante si su valor es igual al del elemento anterior del array. a) Disea un programa C++ que escriba la secuencia de elementos de f eliminando los redundantes, sin emplear arrays auxiliares. b) Disea otro programa C++ que haga lo mismo que el anterior, pero dejando los elementos redundantes sobre el array f. 9.En una entidad bancaria el nmero de cuenta de un cliente se va a formar aadiendo a una determinada cifra un dgito de autoverificacin. Dicho dgito de se calcular de la siguiente forma: a) Multiplicar la posicin de las unidades y cada posicin alternada por dos. b) Sumar los dgitos no multiplicados y los resultados de los productos obtenidos en c) Restar el nmero obtenido en el apartado 2 del nmero ms prximo y superior a
Codifica un programa que vaya aceptando nmeros de cuenta y compruebe mediante autoverificacin si el nmero introducido es correcto o no. El proceso se repetir hasta que se introduzca un cero como nmero de cuenta.
___________________________________________________________________________
Elementos de Programacin Arrays Pg 30