Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: novalida en 15 Marzo 2011, 22:18 pm



Título: Uso de matrices o vectores de punteros
Publicado por: novalida en 15 Marzo 2011, 22:18 pm
Hola,
estoy volviendo a dar un repaso a C++ y como no tengo nada de experiencia me surge la pregunta de para qué se puede utilizar una matriz o un vector de punteros en un programa.
Si alguien me puede poner un par de ejemplos ser lo agradecería.

Un saludo y gracias por ayudarme a aprender :)


Título: Re: Uso de matrices o vectores de punteros
Publicado por: Don Pollo en 16 Marzo 2011, 01:19 am
Hay dos formas de declarar vectores o matrices en C/C++. Una de ellas es declararlos de forma estática, tal que así:

Código
  1. [tip] vector[tam];
  2.  
  3. //[tip] es el tipo de dato que contiene el vector
  4. //tam es el tamaño (el número de "casillas") que va a tener dicho vector

Este tipo de declaración se caracteríza por el hecho de que el vector se crea justo al comienzo de la función que se está ejecutando y tiene un tamaño invariable. En este tipo de declaración no puedes meter más elementos que "casillas" tiene el vector, pero si puedes meter menos, con el consecuente desperdicio de memoria que produce al ser estático y no poder variar su tamaño.
Para las matrices estáticas sería algo parecido, pero con dos tamaños:

Código
  1. [tip] matriz[filas][columnas]
  2. //[filas] es el número de filas que va a tener la matriz. Idem para [columnas]

Para acceder a la "casilla" de un vector estático sólo hay que saber la posición de dicha "casilla", teniendo en cuenta que empieza desde 0. Por ejemplo:

Código
  1. vector[4]=7
  2. //Estamos metiendo en la "casilla" 5 el valor 7.

Por supuesto, cada "casilla" del vector se puede operar con ella como si fuese una variable cualquiera.

En la declaración de vectores y matrices por punteros la cosa cambia. En este tipo de declaración el tamaño si es variable y podremos modificarlo a nuestro antojo.
Un puntero es una variable que apunta a otra variable. Sabiendo esto, para definir un vector por punteros, lo que debemos hacer primero es definir un puntero que inicialmente no apuntará a nada (realmente apuntará a basura) para después hacer que apunte a nuestro vector/matriz.

Primero declaramos el puntero:

Código
  1. [tip] *puntero;
  2. //En caso de ser un vector

Para reservar memoria para el vector al que queremos que apunte nuestro puntero, debemos usar la función "malloc" (si se trata de C) o la función "new" (si se trata de C++).
Si se trata de C haremos lo siguiente:

Código
  1. puntero = ([tip]*)malloc(tam*sizeof([tip])); //Si lo queremos con casting en C
  2. ó
  3. puntero = malloc(tam*sizeof([tip])); //Si lo queremos sin casting en C
  4. puntero = new [tip][tam] //Si se trata de C++

Malloc hace que todas las "casillas" que hemos declarado estén llenas de basura, para ello existe otra función llamada calloc que hace lo mismo que malloc pero inicializa las "casillas" a 0. Para añadir elementos al vector disponemos de la función realloc.
Y con esto ya tenemos definido nuestro vector dinámico en memoria.

El caso de la matriz es más complejo, ya que deberemos crear un puntero doble. Esto es un puntero que apunta a otro puntero. Esto es así, porque deberemos crear un puntero que apunte a un vector de punteros y hacer que cada "casilla" de este vector, apunte a una fila de la matriz. Algo así:

(http://4.bp.blogspot.com/_vooP-k3QJww/RyVGqdozgzI/AAAAAAAAABg/4BYR3CjB7to/s320/Array2d.png)

Para ello, debemos definir primero nuestro puntero doble:

Código
  1. [tip] **puntero;

Ahora reservamos tanta memoria para el vector de punteros como filas queremos que tenga la matriz:

Código
  1. *puntero = ([tip]*)malloc(num_filas*sizeof([tip])); // Aquí no tengo muy claro si sería [tip]* o [tip]**

Y por último, deberemos crear un bucle para ir reservándo memoria para cada "casilla" de ese vector:

Código
  1. for(i=0; i<num_filas; i++) puntero[i] = ([tip]*)malloc(num_columnas*sizeof([tip]));

Siempre que quieras añadir o quitar columnas, deberás ejecutar el bucle por seguridad para que al final unas filas no tengan más columnas que otras.
Y así, ya tenemos declarado nuestra matriz, con elementos de tipo [tip], en memoria.

En estos ejemplos últimos sólo he usado la sintaxis de C, si quieres hacerlo para C++, sólo tienes que cambiar la sintaxis por la que te puse en la declaración del primer vector unidimensional (la de "new").

En resumen: Los vectores estáticos se crean en tiempo de compilación y son de tamaño invariable y los dinámicos se crean en tiempo de ejecución y son de tamaño variable.

Ruego que si véis algún fallo me lo digáis para poder corregirlo.

Espero haberte sido de ayuda  ;D

Un saludo!