Está en la página 1de 11

PRÁCTICA 7

Vectores en C++
Hasta ahora en las prácticas todos los datos que hemos manejado eran “simples”: enteros, reales,
carácter.... En esta práctica veremos cómo se trabaja con vectores, que son los datos estructurados
más sencillos y habituales, además de ser imprescindibles para el tratamiento de datos a los que se
quiere acceder de manera directa.

1 Vectores en C++
Un vector (array, en inglés) es una estructura de datos que nos permite almacenar una colección de
datos, todos ellos del mismo tipo, que a su vez puede ser simple o estructurado. Frente a otros tipos
de estructuras, un vector se caracteriza porque:
• los elementos del vector se almacenan en posiciones contiguas de memoria.
• existe un único nombre de variable que representa a todos los elementos, diferenciándose éstos
por un índice entero, que varía entre 0 y el tamaño del vector menos uno.
• se puede acceder de manera directa a los elementos del vector.

1.1 Declaración de una variable de tipo vector en C++


Tipo_componentes variable_vector[tamaño];

Ejemplo:
Declaración de una variable, de nombre v, de tipo vector de enteros de tamaño 10
int v[10];

1.2 Índices en C++


C++ indexa los elementos de un vector comenzando en 0 (cero)
Ejemplo
En el ejemplo anterior, los 10 elementos del vector int v[10] son:
v[0], v[1], v[2], ..., v[8], v[9]

El quinto elemento del vector es v[4]


1
Informática. Práctica 7.
Vectores en C++

Otro detalle importante es que C++ no realiza comprobación de “salida de rango” en los vectores, es
decir, no detiene la asignación de valores o acceso a valores fuera del vector. Es el programador
quien se ha de encargar de ello. De esta forma, y siguiendo el ejemplo anterior, una expresión en la
que apareciera v[12] no generaría un error al compilar un programa, pero estaríamos accediendo a
una posición de memoria que no estaba previamente reservada. En el caso de acceso a las
componentes el problema consistiría en la no obtención de los resultados deseados, pero en el caso
de asignación de valores a componentes podríamos "machacar" datos de zonas prohibidas de
memoria, pudiendo incluso bloquear el ordenador. Debemos ser pues especialmente cuidadosos
en el manejo de vectores.
C++ no realiza comprobaciones de salida de rango en el acceso a posiciones de un vector

1.3 Vectores bidimensionales: matrices


Recordemos que el tipo de un vector puede ser cualquiera, incluso un tipo estructurado. En el caso
particular de que lo que queramos definir sea un vector de vectores, podemos usar la sintaxis:
Tipo_componentes variable_matriz[tamaño1][tamaño2];

con lo que definiríamos una matriz, especialmente útiles en el diseño de tablas y en aplicaciones
matemáticas.
Ejemplo
Para crear una matriz m de 2 filas por 3 columnas, con sus elementos de tipo real, escribiríamos:
float m[2][3];

Los índices siguen comenzando en cero, con lo que en este ejemplo los cuatro elementos de la
matriz serían:
m[0][0], m[0][1], m[0][2], m[0][1], m[1][0], m[1][1], m[1][2]

1.4 Inicialización de vectores


En el momento de declarar un vector, se nos da la posibilidad de dar valores a los distintos
elementos. Para ello debemos poner entre llaves y separados por comas los valores que les
queremos dar a los respectivos elementos.
Ejemplo
La declaración:
int v[10]={1,2,3,4,5,6,7,8,9,10};

asigna 1 al elemento v[0], 2 al elemento v[1], 3 al elemento v[2], etc.


Si se proporcionan valores iniciales, está permitido omitir el tamaño del vector, y en ese caso el
tamaño vendrá determinado de manera automática por el número de valores especificados.
Ejemplo
La declaración:
char v[ ]={'a','b','c'};

crea un vector de tamaño 3, asignando ‘a’ al elemento v[0], ‘b’ al elemento v[1] y ‘c’ al elemento
v[2].
2
Informática. Práctica 7.
Vectores en C++

En el caso de inicialización de matrices, debemos tener en cuenta que el primer índice que varía es el
situado a la derecha: C++ trata las matrices por filas.
Ejemplo
La declaración:
float m[2][3]={1,2,3,0,1,2};

asigna 1 al elemento m[0][0], 2 al elemento m[0][1], 3 al elemento m[0][2], 0 al elemento


m[1][0], 1 al elemento m[1][1] y 2 al elemento m[1][2].

1.5 Uso de vectores como parámetros


Los vectores, como cualquier otra variable, pueden usarse como parámetro de una función. Para
ello, tanto en la declaración (prototipo) como en la cabecera de la definición de la función debe
especificarse el vector de la siguiente manera:
tipo []

es decir, que no es necesario especificar entre los corchetes la dimensión del vector, sino
simplemente informar a la función de que el parámetro es un vector. Para ello añadimos los
corchetes al tipo de datos básico de cada elemento del vector 1.
Los vectores en C++ son siempre parámetros de entrada-salida: su contenido puede ser modificado
por la función que los recibe, y esos cambios seguirán vigentes en el módulo llamador.
En C++ los vectores son siempre parámetros de entrada/salida y además no debe utilizarse el &
para indicarlo.
Otra peculiaridad de C++ es que no permite que una función devuelva como resultado un dato de
tipo vector (en la orden return). Por tanto, si necesitamos que un subprograma devuelva como
resultado un vector, deberemos utilizar una acción2.
En C++ una función no puede devolver como resultado un vector (en la orden return).
Para una mayor comprensión de estas ideas, observa el ejemplo al final de la práctica.

2 Cadenas de caracteres en C++ (estilo C)


Una cadena de caracteres (al estilo C) es un vector de elementos de tipo carácter con una
característica especial: el último elemento del vector debe ser el carácter especial “nulo”, que se
representa con '\0'. Esta marca es utilizada por el compilador como marca de final de la cadena: al
encontrar el '\0', el compilador sabe que la cadena que está tratando ha terminado. La necesidad
de introducción de este carácter especial obliga a que tengamos cuidado al declarar vectores de
caracteres que vayan a almacenar cadenas. Si queremos almacenar una cadena que tiene 10
caracteres, debemos declarar un vector de tamaño 11 para que se pueda guardar también el '\0'.
0 1 2 3 4 5 6 7 8 9 10

1 Con matrices podemos obviar la primera dimensión, pero debemos incluir obligatoriamente la segunda.
Ejm. tipo [][tamaño2]

2 Para indicar que un subprograma C devuelve un vector hay que recurrir al concepto de puntero, lo que
excede el alcance de esta asignatura introductoria. Será materia de asignaturas futuras de la carrera.
3
Informática. Práctica 7.
Vectores en C++

'H' 'o' 'l' 'a' ' ' 'M' 'a' 'r' 'í' 'a' '\0'
Es necesario observar que las cadenas son vectores de caracteres, pero que no necesariamente
todos los vectores de caracteres son cadenas: para que un vector de caracteres sea una cadena debe
tener el carácter '\0' como último elemento.
C++ reconoce constantes de tipo cadena, que son los caracteres que aparecen entre comillas dobles
("").
Ejemplo
"Hola María" es una constante de tipo cadena en C++.

2.1 Inicialización de vectores para almacenar cadenas


Si al declarar un vector de caracteres deseamos darle un valor inicial de tipo cadena, tenemos dos
posibilidades:
1. Especificar la cadena entre comillas dobles, omitiendo el '\0', aunque manteniendo el
tamaño del vector como si estuviera:
char cadena[11]="Hola María";
Ten en cuenta que también es posible declarar un tamaño superior al de la longitud de la
cadena. Esto será muy habitual cuando queramos usar una misma variable para contener
diferentes valores de tipo cadena de caracteres. Deberíamos especificar el tamaño del
vector de char teniendo en cuenta la cadena más larga que vayamos a tener; o un valor lo
suficientemente grande si no sabemos a priori el tamaño máximo de las cadenas con las que
trabajaremos.
const int TAM_MAX = 10;
char cadena[TAM_MAX + 1] = "Hola"; // +1 para que quepa el '\0'

0 1 2 3 4 5 6 7 8 9 10

'H' 'o' 'l' 'a' '\0'


2. Especificar la cadena entre comillas dobles, omitiendo el '\0', y sin especificar tamaño para
el vector. El compilador tomará el tamaño adecuado, reservando también espacio para el
'\0':
char cadena[]="Hola";
Aunque la segunda forma es la más recomendable, ya que nos evita tener que contar los caracteres
de la cadena con que estamos inicializando, la primera será necesaria cuando queramos que el
vector tenga un tamaño mayor que el de la cadena inicial (si por ejemplo pensamos que más
adelante en el programa se pueda almacenar una cadena de más caracteres en el mismo vector).

2.2 Lectura de cadenas en C++


El problema que presenta cin para lectura de cadenas es que no admite espacios en blanco.
Observa el siguiente ejemplo:

char cadena[15];
...
cin >> cadena;
4
Informática. Práctica 7.
Vectores en C++

cout << cadena;


...

Si introducimos por teclado la cadena “Hola a todos” (sin las comillas), tras la primera lectura el valor
de cadena será “Hola”, es decir, que se omite todo lo que va tras el primer espacio en blanco. Esto
es debido a que los espacios en blanco actúan como “marca de final de cadena”. En la segunda
lectura, el valor que se lee para cadena sería “a”.
Para evitar este problema, utilizaremos el método cin.getline(variableCadena,tamaño). Este
método lee una cadena de caracteres que almacena en variableCadena y limita el número de
caracteres leídos al valor de tamaño., incluido el '\0' final (es decir, lee como máximo tamaño-1
caracteres significativos). Con el uso de tamaño evitamos que un usuario mal intencionado
introduzca código malicioso en el sistema (es lo que se denomina inyección de código). Ante una
lectura de una cadena de caracteres con el método cin.getline el usuario puede escribir el
número de caracteres que quiera, pero el sistema leerá, como máximo, el número indicado en
tamaño. De esta forma garantizamos que no vamos a desbordar el tamaño de la variable cadena.
Ejemplo
char cadena[ ]="Hola";
...
cin.getline(cadena,5);
cout<<cadena;
...

Para leer cadenas en C++ por teclado, usar cin.getline()

2.3 Otras funciones de C++ para el manejo de cadenas


Como puedes constatar realizando cualquier búsqueda en Internet, hay muchas funciones
disponibles en C/C++ para trabajar con cadenas. Aquí mostraremos tres de las más utilizadas:
strlen, strcpy y strcmp. Todas ellas tienen su prototipo en el fichero de cabecera <cstring>.
int strlen (cadena)
Su nombre viene de la contracción de string length (longitud de cadena). Devuelve el número de
caracteres de la cadena que se le pasa como parámetro, sin contar el carácter '\0'. Por ejemplo,
strlen("hola") devuelve 4.
Ten cuidado de distinguir entre el tamaño máximo de la cadena y la longitud de la cadena. Por
ejemplo, en
const int TAM_MAX = 10;
char cadena[TAM_MAX + 1] = "Hola"; // +1 para que quepa el '\0'
El tamaño máximo de la cadena (los caracteres que caben) es 10, pero su longitud es 4.
void strcpy (variableCadena, cadena)
Su nombre viene de la contracción de string copy (copia de cadena). Copia (asigna) la cadena que
va como segundo parámetro en la variable de tipo cadena que va como primer parámetro. Por
ejemplo, teniendo

char cadena[15]
strcpy(cadena,"hola")

5
Informática. Práctica 7.
Vectores en C++

obtendríamos como resultado que cadena contendrá “Hola”


int strcmp (cadena1, cadena2)
Su nombre viene de la contracción de string compare (comparación de cadenas). Sirve para
comparar dos cadenas lexicográficamente (es decir, por orden alfabético). No compara cadenas
por tamaño. Devuelve un entero negativo si la primera es mayor que la segunda, un entero
positivo si la primera es menor que la segunda y cero si las dos cadenas son la misma.
strcmp("Ala","Hola"); // Devuelve un valor <0
strcmp("Hola","Ala"); // Devuelve un valor >0
strcmp("Hola","Hola"); // Devuelve 0

3 Un ejemplo
En el siguiente ejemplo se muestra un programa en C++ que calcula el máximo de N números
enteros introducidos por teclado. Los N números se almacenan en un vector. Observa cómo se
define una constante (TAM) para fijar el tamaño del vector, de forma que no se debe superar ese
tamaño (N debe ser menor que él). Presta atención también al uso de los vectores como
parámetros: observa que desde el punto de vista del subalgoritmo de lectura, el vector es un
parámetro de salida, que llega vacío al subprograma y sale de él con valores. Recuerda que en C/C++
los vectores son siempre tratados como parámetros de entrada/salida y que además no hay que
utilizar el & para indicarlo.
#include <iostream>
using namespace std;

void leeVector(int [],int);


int maximoVector(int [], int);

int main()
{
const int TAM = 100;
int lista[TAM];
int n;

cout << endl << "¿Cuántos elementos?(debe estar entre 1 y " << TAM << "): ";
cin >> n;
leeVector(lista, n);

cout << endl << "Máximo de los " << n << "números: " << maximoVector(lista,n);
return 0;
}

// por ser un vector, v es un parámetro de entrada/salida, aunque no tenga el &


void leeVector(int v[],int n)
{
int i;

for(i=0;i<n;i=i+1)
{
cout << endl << "Introduce elemento " << i;
cin >> v[i];
}
6
Informática. Práctica 7.
Vectores en C++

int maximoVector(int v[],int n)


{
int i;
int maxi;

maxi=v[0];

for(i=1;i<n;i++)
{
if(v[i] > maxi)
{
maxi=v[i];
}
}
return maxi;
}

7
Informática. Práctica 7.
Vectores en C++

4 Sesión de prácticas
4.1 Primer ejercicio
Con este ejercicio aprenderás como:
• Declarar vectores en C++ y acceder a sus componentes
Traduce el siguiente seudocódigo a C++. Edita, guarda con el nombre P7EJ1, compila y ejecuta el
programa. Recuerda que C++ indexa los vectores comenzando en 0.
Especificación:
Entrada: dni
Salida: letra del NIF

algoritmo calculo NIF


variables
entero dni
carácter letraNIF
principio
leer(dni)
letraNIF=calculoletraNIF(dni)
escribir(letraNIF)
fin

función calculoletraNIF(entero dni) devuelve carácter


variables
carácter listaLetrasNIF[23]= "TRWAGMYFPDXBNJZSQVHLCKE"
entero resto
principio
resto = dni MOD 23
devuelve(listaLetrasNIF[resto])
fin

4.2 Segundo ejercicio


Con este ejercicio repasarás como:
• Trabajar con funciones en C++.
• Usar vectores en C++.
• Completar programas.
Aprenderás como
• Escribir estructuras for.
• Usar vectores como parámetros en C++.
Puedes recuperar este programa, fichero P7EJ2.
En este programa calculamos la media de una lista de números enteros que, introducidos por
teclado, se almacenan en un vector. Cuando esté completo, comprueba que el programa funciona
para alguna serie de valores que tú introduzcas, y compruébalo también para el conjunto {1,-1,2}
(media 0.666667).
/*
AUTOR: profesores de Informática

8
Informática. Práctica 7.
Vectores en C++

DESCRIPCION: Calcula la media de una lista de números enteros (máximo 100)


ENTRADAS: Número de números (n) y vector de números enteros
SALIDAS: media de los n números
ERRORES:
*/
#include <iostream>
using namespace std;

void leeVector(int [],int);


......................... /*declaración del subprograma de cálculo de la media*/

int main()
{
const int TAM = 100;
int n;
..............

float media;
cout<<endl<<"¿Cuántos elementos?(debe estar entre 1 y " << TAM << "): ";
cin>>n;
.............. /* Llamada a la acción leeVector*/
.............. /* Llamada a la función de calculo de la media */
cout<<endl<<"La media de los "<< n <<" números es "<< media;
return 0;
}

void leeVector(int v[],int n)


{
int i;

for(i=0; i<n; i++)


{
cout<<endl<<"Introduce elemento "<< i;
cin>>v[i];
}
}

...................... // Cabecera de la definición de la función


{
int i;
.............
.............

suma=0;
.........

for (............)
{
suma=suma+.........
}

media=suma/n;
................
}

4.3 Tercer ejercicio


Descarga el programa (incompleto) p7Ej3
1) Escribe una función con la siguiente cabecera:

9
Informática. Práctica 7.
Vectores en C++

función palíndromo (carácter palabra[], entero nElem) devuelve lógico

de tal manera que devuelva VERDAD si la palabra que se le pasa como parámetro es un
palíndromo, es decir, se lee igual de izquierda a derecha que de derecha a izquierda (por
ejemplo, alla, oso, rasarson palíndromos), y FALSO en caso contrario.
2) Crea un programa completo en C++ que lea por teclado una palabra, llame a la función
anterior y muestre por pantalla si el texto es o no un palíndromo. La lectura puede hacerse
usando cin.getline, obteniendo luego su tamaño con la función strlen.
3) Mejora lo hecho en el primer apartado permitiendo frases. Por ejemplo, dabale arroz a la
zorra el abad es un ejemplo de palíndromo. Para poder utilizar lo ya hecho, basta con
diseñar una nueva acción que, dado un vector de caracteres (y su tamaño), construya el
vector que resulta de eliminar sus espacios en blanco (dando también como salida su
tamaño).

4.4 Cuarto ejercicio


Dos palabras son anagramas cuando una se obtiene a partir de la otra mediante una reordenación
de las letras que la forman.
Ejemplo: AMOR, MORA, ROMA, RAMO son anagramas entre ellas, pero no lo son con AROMA o
REMO
Escribe un subalgoritmo que dados v y w de tipo vector de caracteres (tamaño 15) y longitud n y m
respectivamente determine si w es un anagrama de v.
Crea un programa completo en C++ que permita introducir las dos palabras (utiliza un subprograma
si lo consideras oportuno), llame al subprograma anterior y muestre por pantalla si las palabras son
o no anagramas.
NOTA: como simplificación considera que no se pueden repetir letras en los vectores v y w.
4.4.1 Cuarto ejercicio de otra manera
Repite el ejercicio anterior pero trabajando con cadenas de caracteres. Es decir, escribe un
subalgoritmo que, dadas cad1 y cad2 cadenas de caracteres (tamaño máximo 15 caracteres)
determine si cad2 es un anagrama de cad1. Dos consideraciones importantes:
• Ya no debemos preocuparnos de gestionar explícitamente la longitud de las cadenas, porque
podemos calcularla usando la función strlen. Esta función contará el número de caracteres
de la cadena hasta encontrar el '\0'.
• Para declarar una cadena en la que “quepan” 15 caracteres como máximo debes declarar un
vector de char de tamaño 16. El componente adicional es para el carácter '\0'.
const int NUM_CARACT = 15;
char cad1 [NUM_CARACT + 1];
Crea un programa completo en C++ que permita introducir las dos cadenas de caracteres (usando
cin.getline), llame al subprograma anterior y muestre por pantalla si las palabras son o no
anagramas. Sigue considerando como simplificación que no se pueden repetir letras en las cadenas
cad1 y cad2.
NOTA: Ten cuidado al introducir el texto de las cadenas y no sobrepases el tamaño máximo de 15
caracteres, porque si lo haces, el 2º getline no funcionará.

10
Informática. Práctica 7.
Vectores en C++

4.5 Quinto ejercicio


Dados dos vectores de enteros (tamaño 100), viejo de dimensión nv y altas de dimensión na,
ordenados de forma creciente, diseña un subalgoritmo que construya otro vector, nuevo (de
dimensión nv+na <= 200) ordenado de forma creciente, que incluya los elementos de los vectores
viejo y altas.
Crea un programa completo en C++ que permita introducir los dos vectores (viejo y altas) (utiliza
un subprograma si lo consideras oportuno), llame al subprograma anterior y muestre por pantalla el
contenido del vector resultado (nuevo).
Ejemplo.
Dados:
viejo: (2, 4, 5, 8, 13, 14, 38)
altas: (6, 7, 10, 12)
Devolvería:
nuevo: (2, 4, 5, 6, 7, 8, 10, 12, 13, 14, 38)
Nota: Suponer que no hay elementos repetidos

11

También podría gustarte