Dominar punteros y matrices multidimensionales en C
En lenguaje C, una matriz es una colección de valores de tipo similar almacenados en ubicaciones de memoria continua. Cada elemento de una matriz (unidimensional o multidimensional) se identifica mediante uno o más índices enteros únicos.
Un puntero, por otro lado, almacena la dirección de una variable. La dirección del elemento 0 de una matriz es el puntero de la matriz. Puede utilizar el "operador de desreferencia" para acceder al valor al que hace referencia un puntero.
Puede declarar una matriz unidimensional, bidimensional o multidimensional en C. El término "dimensión" se refiere al número de índices necesarios para identificar un elemento en una colección.
Punteros y matrices unidimensionales
En una matriz unidimensional, cada elemento se identifica mediante un único número entero:
int a[5] = {1, 2, 3, 4, 5};
Aquí, el número "1" está en el índice 0, "2" en el índice 1, y así sucesivamente.
Una variable que almacena la dirección del elemento 0 es su puntero −
int *x = &a[0];
Simplemente, el nombre de la matriz también apunta a la dirección del elemento 0. Entonces, también puedes usar esta expresión −
int *x = a;
Ejemplo
Dado que el valor del puntero aumenta según el tamaño del tipo de datos, "x++" mueve el puntero al siguiente elemento de la matriz.
#include <stdio.h>
int main(){
int arr[] = {1, 2, 3, 4, 5};
int length = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int *ptr = arr;
while (i < length){
printf("arr[%d]: %d \n", i, *(ptr + i));
i++;
}
return 0;
}
Salida
Cuando ejecute este código, producirá el siguiente resultado:
arr[0]: 1 arr[1]: 2 arr[2]: 3 arr[3]: 4 arr[4]: 5
Punteros y matrices bidimensionales
Si una matriz unidimensional es como una lista de elementos, una matriz bidimensional es como una tabla o una matriz.
Se puede considerar que los elementos de una matriz 2D están organizados lógicamente en filas y columnas. Por lo tanto, la ubicación de cualquier elemento se decide mediante dos índices, su número de fila y su número de columna. Tanto los índices de filas como de columnas comienzan desde "0".
int arr[2][2];
Una matriz de este tipo se representa como −
Cabe señalar que la disposición tabular es sólo una representación lógica. El compilador asigna un bloque de bytes continuos. En C, la asignación de la matriz se realiza en forma de filas principales, lo que significa que los elementos se leen en la matriz en forma de filas.
Aquí, declaramos una matriz 2D con tres filas y cuatro columnas (el número en el primer corchete siempre se refiere al número de filas) como −
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
El compilador asignará la memoria para la matriz 2D anterior en orden de filas. Suponiendo que el primer elemento de la matriz está en la dirección 1000 y el tamaño del tipo "int" es de 4 bytes, los elementos de la matriz obtendrán las siguientes ubicaciones de memoria asignadas:
Asignaremos la dirección del primer elemento del array num al puntero ptr usando la dirección del operador &.
int *ptr = &arr[0][0];
Ejemplo 1
Si el puntero se incrementa en 1, pasa a la siguiente dirección. Se puede acceder a los 12 elementos de la matriz "34" en un bucle de la siguiente manera:
#include <stdio.h>
int main(){
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
};
// pointer ptr pointing at array num
int *ptr = &arr[0][0];
int i, j, k = 0;
// print the elements of the array num via pointer ptr
for (i = 0; i < 3; i++){
for (j = 0; j < 4; j++){
printf("%d ", *(ptr + k));
k++;
}
printf("\n");
}
return 0;
}
Salida
Cuando ejecute este código, producirá el siguiente resultado:
1 2 3 4 5 6 7 8 9 10 11 12
En general, la dirección de cualquier elemento de la matriz utiliza la siguiente fórmula:
add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j) * sizeof(array_type)]
En nuestra matriz 34,
add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044
Puede consultar la figura anterior y confirma que la dirección de "arr[3][4]" es 1044.
Ejemplo 2
Utilice el puntero de desreferencia para recuperar el valor en la dirección. Usemos esta fórmula para recorrer la matriz con la ayuda de su puntero −
#include <stdio.h>
int main(){
// 2d array
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int ROWS = 3, COLS = 4;
int i, j;
// pointer
int *ptr = &arr[0][0];
// print the element of the array via pointer ptr
for (i = 0; i < ROWS; i++){
for (j = 0; j < COLS; j++) {
printf("%4d ",*(ptr + (i * COLS + j)));
}
printf("\n");
}
return 0;
}
Salida
Cuando ejecute este código, producirá el siguiente resultado:
1 2 3 4 5 6 7 8 9 10 11 12
Punteros y matrices tridimensionales
Una matriz tridimensional es una matriz de matrices bidimensionales. Dicha matriz se declara con tres subíndices:
int arr [x] [y] [j];
Esta matriz se puede considerar como un número "x" de capas de tablas, cada tabla tiene "x" filas y un número "y" de columnas.
Un ejemplo de una matriz 3D es −
int arr[3][3][3] ={
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};
Un puntero a la matriz 3D se puede declarar como −
int * ptr = &arr[0][0][0];
Sabiendo que el nombre de la matriz en sí es la dirección del elemento 0, podemos escribir el puntero de una matriz 3D como −
int * ptr = arr;
Cada capa de filas "x" y columnas "y" ocupa −
x * y * sizeof(data_type)
Número de bytes. Suponiendo que la memoria asignada a la matriz 3D "arr" como se declaró anteriormente comienza desde la dirección 1000, la segunda capa (con "i =1") comienza en la posición 1000 + (3 3) 4 =1036 bytes.
ptr = Base address of 3D array arr
Si JMAX es el número de filas y KMAX es el número de columnas, entonces la dirección del elemento en la fila 0 y la columna 0 del primer segmento es −
arr[1][0][0] = ptr + (1 * JMAX * KMAX)
La fórmula para obtener el valor de un elemento en la j-ésima fila y la k-ésima columna del i-ésimo segmento se puede dar como −
arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))
Ejemplo:impresión de una matriz 3D mediante desreferenciación de puntero
Usemos esta fórmula para imprimir la matriz 3D con la ayuda de la desreferenciación del puntero −
#include <stdio.h>
int main(){
int i, j, k;
int arr[3][3][3] = {
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};
int JMAX = 3, KMAX = 3;
int *ptr = arr; // &arr[0][0][0];
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
for(k = 0; k < 3; k++){
printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k)));
}
printf("\n");
}
printf("\n");
}
return 0;
}
Salida
Cuando ejecute este código, producirá el siguiente resultado:
11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 38 39
En general, acceder a una matriz con un puntero es bastante similar a acceder a una matriz con representación de subíndice. La principal diferencia entre los dos es que la declaración con subíndice de una matriz asigna la memoria estáticamente, mientras que nosotros podemos usar punteros para la asignación de memoria dinámica.
Para pasar una matriz multidimensional a una función, necesita usar punteros en lugar de subíndices. Sin embargo, usar una matriz con subíndices es más conveniente que usar punteros, lo que puede resultar difícil para los nuevos estudiantes.
Lenguaje C
- Funciones de biblioteca estándar de C
- ¿Qué es el lenguaje de programación C? Fundamentos, Introducción, Historia
- Tutorial de matriz de C#:crear, declarar, inicializar
- C# Clase parcial y método parcial
- C - Punteros
- Modificadores de acceso de C#
- C - Variables
- Tipos de variables de C++
- Operadores en C++
- Gestión de memoria C++:nuevo y eliminar
- Pasar matriz a una función en programación C++