Anuncios Google

[MINI GUÍA C++] Vectores (Parte 1) (En portada)

Nivel: Iniciado.
Requisitos:
Conocer algo de C ó C++ y saber qué es un vector o array unidimensional.

Todavía leo por aquí mucha gente que se cree que C++ es un C con 4 extensiones. C++ es mucho más que eso, su forma de tratar los datos va más allá de C y muchas veces ni se le parece.

Aquí voy a mostrar como tratar un vector o matriz de una dimensión "a lo C++", es decir, usando la librería estándar que este lenguaje incorpora.

Hay que intentar comprender que un vector se trata como un objeto o clase, nada que ver con el vector de C.

Ejemplo de declaración.

#include <vector>
using namespace std;
 
vector<int> foo;

Si os fijáis, la sintaxis es muy simple, se indica el tag vector y entre los símbolos "<>" el tipo de datos que contendrá, en este caso enteros.

Vamos a suponer que queremos crear un vector de 8 elementos.

#include <vector>
using namespace std;
 
vector<int> foo(8);

Con esta instrucción, asignamos 8 elementos al vector, también nos puede interesar a la misma vez que creamos los elementos ponerles un valor por defecto, vamos a inicializarlos a cero (recordad que tanto C como C++ no inicializan las variables al crearlas), el código sería:

#include <vector>
using namespace std;
 
vector<int> foo(8, 0);

También se puede crear un vector que sea la copia de otro vector

#include <vector>
using namespace std;
 
vector<int> foo(8);
vector<int> copia_de_foo(foo);

Este código de aquí puede parecer raro porque en el primero ponemos como parámetro un entero y en el segundo ponemos otro vector. En C, no se puede cambiar el tipo de dato que se envía a una misma función, en C++ sí. A esto se le llama "sobrecarga de funciones o métodos" y permite crear funciones con el mismo nombre y distintos parámetros, en este caso se trata no de una función, sino de un constructor: El constructor de la clase vector (recordad que vector es una clase, no una variable).

Es posible que no sepamos el número de elementos en un principio y queramos ir añadiéndolos poco a poco según nuestra aplicación, para ello usamos la instrucción push_back, que añade un elemento al final del vector. También se puede eliminar el último elemento con pop_back().

#include <vector>
using namespace std;
 
int main() {
   vector<int> foo;
   for (int i = 0; i < 8; i++)
      foo.push_back(99);
}

Hemos creado un vector de 8 elementos con el valor 99. Un detalle que muestra la diferencia con C, es el bucle for en el que hemos creado la variable "i". Sólo tiene valor en el bucle, una vez salimos de él, desaparece. Esto es útil porque nos evita tener que inicializar al principio variables de bucle, que como se compartirán en distintos bucles, pueden dar lugar a confusión o error. Si ejecutáis este código, dará error, porque "i" ya no existe porque no estamos en el bucle

#include <vector>
#include <iostream>
using namespace std;
 
int main() {
   vector<int> foo;
   for (int i = 0; i < 8; i++)
      foo.push_back(99);
   cout << "El valor de i es: " << i;
}

Una puntualización sobre los vectores y que hay que tener en cuenta al desarrollar tanto en C como en C++ es la optimización de memoria. Si quisieramos añadir/eliminar 20000 elementos en nuestra aplicación, pero esto se hará a lo largo de la misma y en diferentes momentos, al final generaríamos las famosas "memory leaks" o lagunas de memoria, que harán que los datos de dicho vector no estén consecutivos y al eliminarlos, quedarán huecos difíciles de usar. Una forma de prevenir esto, es reservar un valor de elementos antes de hacer nada con el vector.

#include <vector>
using namespace std;
 
vector<int> foo;
foo.reserve(20000);

Vuelvo a repetir, que esto reserva espacio "consecutivo" en memoria, no añade valores al vector, es posible que tengamos una aplicación en la que a veces usemos 8 elementos y otras veces 20000. En este ejemplo, tendríamos reservados de forma consecutiva en memoria un espacio para trabajar con 20000 elementos sin que ocurran memory leaks.

Se puede cambiar el tamaño del vector de forma dinámica durante la ejecución del aplicación, si se cambia a menos, los últimos elementos sobrantes se eliminarán. Se puede usar opcionalmente un inicializador de valores. Un ejemplo redimensionando 2 vectores con y sin valores iniciales.

#include <vector>
using namespace std;
 
vector<int> foo(8);
vector<int> foo_a_cero(8, 0);
 
foo.resize(25);
foo_a_cero.resize(25, 0);

En la próxima entrega, veremos cómo trabajar con ellos buscando un valor, ordenándolos y recorriéndolos para hacer algo con cada elemento sin teclear apenas código. También con un pequeño "truco" se pueden manejar matrices multidimensionales.


LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Churristian8

A portada con

A portada con prioridad.

Muchas gracias gorrister.

Edito: Ya lo tienes en portada ;-)

Imagen de burnxez

Dudas varias...

Buenas, mi pregunta es ¿Para qué se puede usar dentro de aplicaciones?

Enfocado a juegos creo que lo llevo claro, sería algo similar a como se usan los arrays en Lua para almacenar información y estados de, por ejemplo, un personaje. En este ámbito, ¿Voy bien o estoy equivocado en su uso?

En cuanto a las aplicaciones, no me doy una idea clara sobre cual podría ser el uso más acertado de esta herramienta. He buscado y he encontrado que lo más básico sería un programa que gestionara datos de trabajadores (DNI, salario, horas, etc...) en ese caso, lo entiendo, sin embargo no soy capaz de imaginarme usando una matriz en un programa diferente.

Según entiendo, una matriz reserva memoria consecutiva y en el se almacenan datos que de alguna manera se entrelazan, ¿Correcto?

Si mi anterior afirmación es correcta, entonces por ejemplo, en un reproductor de música se podría usar una matriz para almacenar datos como: Autor, Albúm, Número de Pista, Título, etc... ¿Lo he captado mal?

Ahora, según la Wikipedia, array, vector y matriz es lo mismo, sin embargo leyendo la referencia de C++ me encuentro con que se declaran de forma diferente.

//Array
 
int foo [] = {16, 2, 77, 40, 3}

La sintaxis es similar a la que estoy acostumbrado en Lua, pero no se parece a la que has puesto en el tutorial ni a la que hay en c++.com para declarar una matriz/vector.

Esta es otra duda que me surge, ¿Array es diferente a Vector/Matriz?

Perdón por el mar de texto, espero haberme explicado correctamente.

Saludos.

Imagen de pspgorrister

Un vector es lo mismo que un

Un vector es lo mismo que un array de una dimensión. Es correcto decir también "array unidimensional" o "matriz unidimensional".

Los usos... pues cualquier cosa que quieras meter en un vector, lo que comentas de datos de trabajores, sí, se podrían guardar sus fichas en una clase o estructura y cada ficha sería un elemento del vector por ejemplo. Lo que dices del reproductor, como son datos de tipo diferente Autor = texto, Núm. de pista = numérico, etc. Se pueden usar estructuras, o arrays asociativos, que en C++ se llaman maps. Algo parecido a un vector, pero no exactamente igual. y luego esos datos (que en conjunto son lo mismo) guardarlos en un vector.

Sobre lo que comentas de declarar un vector, también se puede hacer así, *pero* esa no es la forma "pura" de hacerlo. Por un lado si quieres sacarle potencial a C++ debes usar su STL (librería estándar de tipos), que entre otras cosas tiene el cout/cin/cerr, que sustituye a printf(), que ya traté en otra miniguía y también la clase  vector. Para manejar arrays como lo hace C, y no usar la STL, sinceramente yo uso C directamente.

Usar C++ sin Programación Orientada o Objetos y sin usar la STL, es desperdiciar este lenguaje. El problema es que debido a la compatibilidad con C que tiene, para bien o para mal permite hacerlo.


LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.