3 de diciembre de 2018

Arreglos de dos dimensiones (matrices).

   Los arreglos de dos dimensiones también reciben el nombre de arreglos bidimensionales o simplemente matrices.

Conceptos, representación y estructura.
   Los arreglos bidimensionales son una estructura de datos de dos dimensiones de elementos contigüos, relacionados por un mismo tipo de datos y un mismo nombre, donde los elementos son distinguidos por dos índices.

(a) Representación (abstracción) de una matriz.
(b) Representación en memoria de una matriz.
 
    Las figuras anteriores muestran en (a), la representación de una matriz m de cuatro renglones y cuatro columnas (cuadrada). Los renglones y columnas de una matriz en C siempre empiezan en el índice 0, y terminan en el índice tamaño - 1 (3), dónde tamaño se refiere al tamaño, dimensión o longitud del renglón o columna de la matriz respectivamente. Por otro lado, la figura (b) muestra la representación física de la matriz m en la memoria principal de la computadora. Observe que la memoria de la computadora es una estructura lineal y no una estructura cuadrada (bidimensional), por lo que los elementos de la matriz son almacenados linealmente, de tal forma que el elemento m[1][0] es el inmediato posterior del elemento m[0][3], y que el elemento m[2][0] es el inmediato posterior del elemento m[1][3], y así sucesivamente.

   En general, la declaración de un arreglo bidimensional en el lenguaje de programación C tiene la siguiente estructura:

tipo_de_dato nombre_de_la_matriz[TAMAÑO1][TAMAÑO2];

donde:

  • tipo_de_dato es cualquier tipo de dato válido en C.
  • nombre_de_la_matriz es un identificador válido en C.
  • TAMAÑO1 es el número de renglones que tendrá la matriz.
  • TAMAÑO2 es el número de columnas que tendrá la matriz.

Declaración, inicialización, recorrido y uso con funciones.
   El Ejemplo 6.7 muestra la declaración, la inicialización, el recorrido, y el uso de matrices con funciones. Las líneas 6 y 7 definen dos constantes simbólicas M y N para el número de renglones y columnas de la matriz respectivamente. Estas constantes determinarán las dimensiones reales o físicas de matriz1, matriz2 y matriz3, declaradas en las líneas 14 y 15. Note que estas tres matrices tiene la forma de las figuras anteriores.

   Observe también que matriz2 y matriz3 han sido inicializadas en su declaración, esto quiere decir que en tiempo de compilación le son asignados los valores especificados. Los valores asignados están representados en las siguientes figuras:

(a) Inicialización de la matriz2.
(b) Inicialización de la matriz3.
 
    Ahora bien, la línea 14 muestra un tipo de inicialización en secuencia, la cual es posible debido a la forma en que se representa la matriz en la memoria de la computadora.

   En base a lo anterior, los primeros cinco elementos físicos de matriz2 tendrán los valores que se muestran en la figura (a). Los elementos que no son inicializados explícitamente, son puestos en 0 por omisión.

   Por otro lado, la línea 15 muestra una inicialización por renglones para matriz3; este tipo de inicialización se explica mejor con la figura (b) en donde se observa que los tres primeros elementos del renglón 0 están inicializados con los valores especificados (línea 15), mientras que el último de ellos ha sido inicializado por omisión con 0. Antes de continuar, asegúrese de entender lo que sucede con el segundo renglón de inicialización de la matriz3 y su correspondiente representación en la figura (b).

   El ciclo do-while de las líneas 17-20 valida (la validación sólo considera matrices cuyas dimensiones sean de al menos 2x2 y de a lo más MxN. Si bien es cierto que existen matrices de 3x1 o de 1x4 por ejemplo, también es cierto que técnicamente se les puede denominar vectores, por lo que por simplicidad y para motivos de ilustración se ha hecho este tipo  de validación) las dimensiones para la matriz1 específicamente, debido a que el Ejemplo 6.7 define unas dimensiones físicas (líneas 14 y 15), pero controla unas dimensiones lógicas (líneas 21 y 24), y dichas dimensiones lógicas estarán determinadas por las variables m y n (línea 19) para el número de renglones y columnas respectivamente.

   Las figuras de inicialización anteriores  indican también las dimensiones lógicas (indicadas con una elipse) para la matriz2 y la matriz3 respectivamente, mientras que las dimensiones físicas están representadas por la malla (matriz) de 4x4.

   La línea 21 hace el llamado a la función leeMatriz definida en la líneas 33-44. El llamado envía como argumentos la matriz1, y las dimensiones m y n obtenidas en la línea 19.

   Ahora bien, la función leeMatriz define tres parámetros: matriz[ ][N], m y n. Observe que matriz será el nombre con el que la función hará referencia al arreglo bidimensional que reciba, y que la notación [ ][N] le indica al compilador que lo que recibirá será precisamente un arreglo bidimensional. Note también que los primeros corchetes están vacíos mientras que los segundos tienen la dimensión física N declarada para el arreglo (líneas 14 y 15).

   En C, los arreglos de más de una dimensión deben llevar siempre, con posibilidad de omitir únicamente el tamaño de la primera dimensión, el tamaño físico de cada una de las dimensiones restantes, y esto está estrechamente relacionado con la representación física en la memoria de la computadora de los arreglos de n dimensiones.

   La especificación del tamaño de la segunda dimensión para las matrices le indica al compilador cuántos elementos hay por renglón, para así poder determinar en dónde empiezan cada unos de los renglones de la matriz.

   Continuando con el Ejemplo 6.7, la función leeMatriz se encarga de leer de la entrada estándar (línea 40) los elementos que conformarán la matriz lógica determinada por los parámetros m y n. Note cómo los ciclos for de las líneas 36 y 38 están en función de dichos parámetros.

   Por otro lado, las líneas 24, 26 y 28 hacen el llamado a la función imprimeMatriz definida en la líneas 33-44. El primer llamado envía como argumentos a la matriz1 y a las dimensiones obtenidas en la línea 19; mientras que el segundo y tercer llamado envían a la matriz2 y a la matriz3 respectivamente ambas con dimensiones lógicas 2 y 4.

   Finalmente, la función imprimeMatriz definida en las líneas 46-54 define una lista de parámetros análoga a la de la función leeMatriz. La función imprimeMatriz realiza un recorrido por renglones de la matriz matriz para su impresión en la salida estándar. Una posible salida del Ejemplo 6.7 se  muestra en la siguiente figura:

Una posible salida del Ejemplo 6.7.