Definir una matriz

La definición de una matriz de una dimensión se hace de la siguiente forma:

definir_matriz

donde

  • tipo .- indica el tipo de los elementos de la matriz, el cual puede ser cualquier tipo primitivo o definido por el usuario.
  • nombre .- es un identificador que nombra a la matriz.
  • tamaño .- es una constante entera que especifica el número de elementos de la matriz.

Los corchetes modifican la definición normal del identificador para que sea interpretado por el compilador como una matriz.

Veamos las siguientes líneas como ejemplo de definiciones de matrices.

definir_matriz_2

La primera línea crea una matriz identificada por m con 10 elementos de tipo int y que puede almacenar 10 valores enteros:

matriz_10La segunda crea una matriz temperatura de 31 elementos de tipo float. Y la tercera crea una matriz coordenada de 25 elementos de tipo CCoordenadas.

Acceder a los elementos de una matriz

 Para acceder al valor de un elemento de una matriz se utiliza el nombre de la matriz, seguido de un subíndice entre corchetes. Esto es,  un elemento de una matriz no es más  que una variable con subíndice; por lo tanto, se puede utilizar exactamente igual que cualquier otra variable. Por ejemplo, en las operaciones que se muestran a continuación intervienen elementos de una matriz:

elementos_matriz_1

Vemos que para referenciar un elemento de la matriz se puede emplear como subíndice una constante, una variable o una expresión de tipo entero. El subíndice especifica la posición del elemento dentro de la matriz. La primera posición es la cero.

Cuando intentamos acceder a un elemento con un subíndice menor de 0 o mayor que el número de elementos de la matriz C++ no informará de ello porque no realiza ese tipo de chequeo será el sistema operativo quien lo notifique mediante un mensaje de error. Por lo tanto es responsabilidad del programador escribir el código necesario para detectar este tipo de errores.

Por ejemplo veamos que pasa si asignamos un rango superior al asignado:

matriz_2

El listado de arriba da lugar a un resultado impredecible, puesto que intenta asignar el valor del elemento de subíndice 99 al elemento de subíndice 100, que se encuentra fuera del rango 0 a 99 válido.

matriz_2_salida_error

 Para asegurarnos de no exceder accidentalmente los límites de una matriz verificaremos en todo momento que el índice está entre 0 y la longitud de la matriz menos 1. Por ejemplo:

matriz2_listado

y la salida sería:

matriz2_salida

atras

 

Iniciar una matriz

Cuando se define una matriz, sus elementos son automáticamente iniciados, solo si se ha realizado a nivel global; en este caso, igual que sucedía con las variables globales, si la matriz es numérica, sus elementos son iniciados a 0; si es de carácter, al valor ” y si es de puntero, a 0. Si la matriz es local, sus elementos no se inicializaran automáticamente, en este caso, lo único que almacenará será basura. Si la matriz es local pero se declara static, entonces se inicia igual que si fuera global.

Si queremos iniciar una matriz con unos valores determinados en el momento de definirla, lo haremos de la siguiente forma:

matriz3

En el ejemplo anterior, el tamaño de una matriz debe ser igual o mayor que el número de valores especificado. Cuando es mayor, solo serán inicializados explícitamente tantos elementos como valores. El resto de los elementos serán iniciados implícitamente, dependiendo del tipo, a o, a ‘/0’ o a NULL (dirección 0).

Si queremos iniciar todos los elementos de una matriz a 0 en el momento de definirla, podemos hacerlo de la siguiente forma:

matriz_4

Siempre que se inicie una matriz en el instante de su definición, el tamaño puede omitirse; en este caso el número de los elementos se corresponderá con el número de valores especificados. Podemos omitir también el tamaño en los siguientes casos:

  • Cuando se declara como un parámetro formal en una función.
  • Cuando se hace referencia a una matriz declarada en otra parte del programa.

El siguiente programa de ejemplo observamos que la función main define e inicia una matriz x sin especificar explícitamente su tamaño y que el primer parámetro de la función VisualizarMatriz es una matriz m de la cuál tampoco se especifica su tamaño.

matriz3_listado

El primer parámetro de la función VisualizarMatriz es una matriz m de la cuál tampoco se especifica su tamaño. En este caso, ¿cual sería el tamaño de la matriz m? Lógicamente el tamaño de la matriz x pasada como argumento a la función VisualizarMatriz.

matriz3_salida

 Desglosándolo:

desglose1

separador

desglose2separador

desglose3La pregunta que nos hacemos ¿que se ha copiado en m? ¿Se hizo un duplicado de la matriz? No, no se hizo un duplicado. Cuando el argumento es una matriz lo que se pasa es la dirección de esa matriz, o sea, la posición donde comienza el bloque de memoria que ocupa físicamente esa matriz. Dicha dirección viene dada por el nombre de la matriz. Lo cuál significa que C++ pasa las matrices por referencia.

 Según lo expuesto ¿que conoce VisualizarMatriz de la matriz x? Pues la dirección de comienzo, m, y su número de elementos, n.

matrices__5

atras

 

Trabajar con matrices unidimensionales

 Practiquemos la teoría expuesta hasta ahora, vamos a realizar un programa que asigne datos a una matriz unidimensional m de N_ELEMENTOS y, seguidamente,  para la comprobación del trabajo realizado escribiremos el contenido de dicha matriz. Veamos su solución:

  1. Empezamos definiendo la constante N_ELEMENTOS con el fin de fijar los elementos de la matriz.matriz4_listado1
  2. Después, cre4aremos la matriz m con ese número de elementos (N_ELEMENTOS) y definimos el subíndice i para acceder a los elementos de dicha matriz.matriz4_listado2
  3. El siguiente paso es asignar un valor desde el teclado a cada elemento dentro de la matriz.matriz4_listado3
  4. Una vez introducidos los datos en la matriz la visualizamos para comprobar el trabajp realizado.matriz4_listado4

El programa completo se muestra a continuación:

matriz4_salida

atras

 

 Tipo y tamaño de una matriz

 Anteriormente vimos que utilizando typedef podíamos declarar sinónimos de otros tipos fundamentales o derivados. El tipo matriz es un tipo derivado (por ejemplo, int [ ] para una matriz de una dimensión). Con lo cual, podemos declarar un sinónimo de un tipo de matriz así:

tipo_matriz1

La línea anterior define un nuevo tipo, tipo_matriz_id, que define matrices de una dimensión con 100 elementos del tipo double. Luego la siguiente sentencia utiliza este tipo para definir una matriz m:

tipo_2

Tambien en temas anteriores vimos que el operador sizeof daba como resultado el tamaño en bytes de su operando. Pues bien, cuando el operando es una matriz, el resultado es el tamaño en bytes de dicha matriz. Por ejemplo la siguiente línea de código visualiza el número de elementos de la matriz m definida anteriormente:

matriz5_1

 Lo que hemos visto aquí, también se hace extensible a las matrices de varias dimensiones como veremos más adelante.

atras

 

 Vector

La biblioteca estándar de C++ proporciona una plantilla vector definida en el espacio de nombres std y declara en el fichero de cabecera <vector> lo cuál facilita la creación y manipulación de matrices. Por ejemplo, para definir una matriz de una dimensión , la sintaxis a utilizar es:

vector1

donde:

vector

Por ejemplo, la matriz m del ejemplo anterior podría  declararse también así:

vector2

En este caso, al tratarse de un tipo primitivo, los elementos de la matriz son automáticamente iniciados a cero, cosa que no ocurría antes.

Esta forma de declarar una matriz no resulta más complicada y favorece en el sentido de que el número de elementos no necesita ser constante. Por ejemplo:

vector4

También un vector puede ser copiado en una única operación en otro vector, operación que no podemos realizar con las matrices primitivas. Por ejemplo:

vector5

La plantilla vector proporciona métodos para acceder a los elementos del vector, e insertar nuevos elementos, eliminar elementos, obtener el número de elementos, asignar un nuevo tamaño, etc.

atras

 

Acceso a los elementos

Para acceder a un elemento podemos utilizar el operador [ ] o el método at. De la primero manera no disponemos de verificación de sí el índice está fuera del rango y de la segunda si (lo veremos más adelante, en Excepciones).

acceso1

Los métodos front/back permiten acceder al primer y último elemento, respectivamente. Como veremos a continuación, también podemos acceder a los elementos a través de un iterador.

atras

 

Iteradores

Los iteradores se utilizan para navegar a través de los contenedores sin necesidad de conocer el tipo utilizado para identificar los elementos. Los iteradores begin/end ofrecen los elementos en el orden normal (0, 1, 2, …, n-2, n-1); begin apunta al primer elemento de la secuencia y end al elemento siguiente al último.

begin_end

Los iteradores rbegin/rend ofrecen los elementos en el orden inverso (n-1, n-2, …, 1, 0); rbegin apunta al primer elemento de la secuencia inversa y rend al elemento siguiente al último.

rbegin_rend

iteradores4

Observamos que *e es el entero referenciado por e. Esto quiere decir que un iterador define un puntero. Según esto, podríamos escribir también:

iteradores3

atras

 

Tamaño

Para conocer el tamaño de un vector hay que hay que invocar a su método size y para modificar su tamaño, al método resize, en este último caso, los elementos conservados desde el primero hasta el nuevo tamaño permanecen inalterados.

size_resize

Si queremos saber si un vector está vacío, utilizaremos el método empty, éste método devuelve true si el vector está vacío y false en caso contrario.

atras

 

Eliminar elementos

 El método pop_back permite eliminar el elemento del final y el método erase permite eliminar desde un elemento hasta otro.

pop_back_erase

Para eliminar todos los elementos usaremos el método clear.

atras

 

Buscar elementos

El algoritmo find lo tenemos declarado en <algorithm> nos permite buscar un elemento en un contenedor; por ejemplo, en un vector. Esta función devuelve un oterador al primer elemento que coincide con el valor. Por ejemplo:

buscar_elementos

atras

 

Insertar elementos

El método push_back permite añadir  un elemento al final y el método insert permite insertar uno o más elementos en cualquier posición.

push_back

Los métodos push_back y pop_back permiten utilizar un vector como si fuera una pila (las estudiaremos en los próximos temas).

 

.atras

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s