TODOPIC

Lenguajes de programación para PC => C, C#, C++ => Mensaje iniciado por: CompSystems en 19 de Mayo de 2014, 21:26:52

Título: alternativa manejo punteros a matrices bidimencionales
Publicado por: CompSystems en 19 de Mayo de 2014, 21:26:52
Hola, el siguiente ejemplo funciona bien, declaro una matriz bidimensional y un puntero a la primer posicion de la misma, luego simplemente despliego en pantalla cada valor de la matrix de la forma *(ptrName+#), mi deseo es trabajar con el puntero pero con subindices dobles de la forma (ptrName[][]) pero no logre compilarlo exitosamente, alguien de vosotros que me colabore, o los punteros hacia matrices multidimesionales solo se manejan con un solo subindice? si es asi la logica de ubicacacion de elelmentos [filas, cols] se complia por que requeire ver la matriz bidimensional como un arreglo unidimensional  :(

Muchas gracias
Código: C++
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. // protoptipos
  7. void load(int *mat, char, char);
  8. void show(int *mat, char, char); // void show(int mat[][3], int);
  9.  
  10. int main(int argc, char *argv[]){
  11.        
  12.         int vector[4] = { 9, 8, 7, 6 };
  13.         int matrixA[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };  
  14.         //int matrixB[3][2] = { 1, 2, 3, 4, 5, 6 };// ==        { { 1, 2 }, { 3, 4 }, { 5, 6 } }
  15.         int matrixC[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };      // == {{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }
  16.        
  17.         int *ptrMatrixA = &matrixA[0][0]; //  puntero a la matrixA
  18.         int *ptrVector = &vector[0]; // puntero a vector
  19.         //int *ptr1Vector = ptrVector; // puntero a ptr
  20.        
  21.         cout << "vector[4] = { 9, 8, 7, 6 }" << endl;
  22.         cout << "matrixA[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };\n" << endl;
  23.        
  24.         // impresion de elementos
  25.        
  26.         // impresion del 1er elemento usando subindices
  27.         int mat_fila1col1 =  matrixA[0][0]; // usando el nombre de la matrix mas dos subindices, PERO NO OPERA EN LLAMADA DE FUNCIONES
  28.         cout << "Mat: (fila1,col1) = " << mat_fila1col1 << endl; // 1
  29.        
  30.         int vec_col1 = vector[0]; // usando subindices
  31.         cout << "Vect: col1 = " << vec_col1 << endl;  // 9
  32.        
  33.         /////////////
  34.         // impresion del 2do elemento usando subindices
  35.         int fila1col2_mat =  matrixA[0][1]; // usando el nombre de la matrix mas dos subindices
  36.         cout << "\nMat: (fila1,col2) = " << fila1col2_mat << endl; // 2
  37.        
  38.         int vec_col2 = vector[1]; // usando subindices
  39.         cout << "Vect: col2 = " << vec_col2 << endl; // 8
  40.  
  41.         /////////////
  42.         // impresion del 3cer elemento usando subindices
  43.         int fila2col1_mat =  matrixA[1][0];
  44.         cout << "\nMat: (fila2,col1) = " << fila2col1_mat << endl; // 3
  45.        
  46.         int vec_col3 = vector[1]; // usando subindices
  47.         cout << "Vect: col2 = " << vec_col3 << endl; // 7
  48.        
  49.         /////////////  
  50.         // Impresion del 1er elemento usando punteros
  51.         int pmat_fila1col1 =  *(ptrMatrixA+0); // se trata la matriz como un arreglo unidimensional
  52.         cout << "\nMat: (fila1,col1) = " << pmat_fila1col1 << endl; // 1
  53.        
  54.         int pvec_col1 = *(ptrVector+0);
  55.         cout << "Vect: col1 = " << pvec_col1 << endl; // 9  
  56.        
  57.         // Impresion del 2do elemento usando punteros
  58.         int p1mat_fila1col2 =  *(ptrMatrixA+1) ;
  59.         cout << "\nMat: (fila1,col2) = " << p1mat_fila1col2 << endl; // 2  
  60.        
  61.         int p1vec_col2 = *(ptrVector+1);
  62.         cout << "Vect: col2 = " << p1vec_col2 << endl; // 8
  63.        
  64.        
  65.         // Impresion del 1er elemento usando punteros con un subindice []
  66.         int p2mat_fila1col1 =  ptrMatrixA[0] ; // usando 1 subindice
  67.         cout << "\nMat: (fila1,col1) = " << p2mat_fila1col1 << endl; // 1
  68.        
  69.         int p2vec_col1 = ptrVector[0]; // usando subindice
  70.         cout << "Vect: col1 = " << p2vec_col1 << endl;  // 9
  71.        
  72.         // Impresion del 2do elemento usando punteros con un subindice []
  73.         int p3mat_fila1col2 =  ptrMatrixA[1] ; // usando 1 subindice
  74.         cout << "\nMat: (fila1,col2) = " << p3mat_fila1col2 << endl;    
  75.        
  76.         int p3vec_col2 = ptrVector[1]; // usando subindice
  77.         cout << "Vect: col2 = " << p3vec_col2 << endl; // 8    
  78.        
  79.         // Impresion del 3er elemento usando punteros con un subindice []
  80.         int p4mat_fila2col1 =  ptrMatrixA[2] ; // usando 1 subindice
  81.         cout << "\nMat: (fila2,col1) = " << p4mat_fila2col1 << endl; // 3  
  82.        
  83.         int p4vec_col3 = ptrVector[2]; // usando subindice
  84.         cout << "Vect: col3 = " << p4vec_col3 << endl; // 7
  85.        
  86.         // Impresion del 4to elemento usando el nombre con dos subindices
  87.         int p5mat_fila2col2 =  matrixA[1][1] ; // usando 2 subindices
  88.         cout << "\nMat: (fila2,col2) = " << p5mat_fila2col2 << endl; // 4  
  89.        
  90.         // Impresion del 4to elemento usando el puntero nombre con dos subindices entre []
  91.         //int p5mat_fila2col2 =  ptrMatrixA[1][4] ; // usando 2 subindices no se puede de esta forma
  92.         //cout << "\nMat: (fila2,col2) = " << p5mat_fila2col2 << endl; // 4
  93.        
  94.         // Impresion del 4to elemento usando el puntero nombre con dos subindices pero sin []
  95.         unsigned char cols = 2, fila=1, col=1; // en base cero
  96.         int p6mat_fila2col2 =   *(ptrMatrixA + (fila*cols) + col); // usando 2 subindices con doble [] no se puede con punteros, de esta forma si
  97.         cout << "\nMat: (fila2,col2) = " << p6mat_fila2col2 << endl; // 4
  98.        
  99.         // Impresion del 4to elemento usando el puntero nombre con dos subindices pero sin []
  100.         int p7mat_fila2col2 =  *(ptrMatrixA + (fila*cols) + col );
  101.         cout << "\nMat: (fila2,col2) = " << p7mat_fila2col2 << endl; // 4
  102.        
  103.         // [[ (0,0) = 1, (0,1) =2 ]
  104.         //      [ (1,0) = 3, (1,1) =4 ]
  105.         //      [ (2,0) = 5, (2,1) =6 ]]       
  106.                
  107.         // [[ (1,1) = 1, (1,2) =2 ]
  108.         //      [ (2,1) = 3, (2,2) =4 ]
  109.         //      [ (3,1) = 5, (3,2) =6 ]]       
  110.        
  111.         // Impresion del 4to elemento usando el puntero nombre con dos subindices pero con un solo []
  112.         int p8mat_fila2col2 =  ptrMatrixA[ ( fila * cols ) + col ];
  113.         cout << "\nMat: (fila2,col2) = " << p8mat_fila2col2 << endl; // 4
  114.        
  115.        
  116.         // Impresion del 6to elemento usando el puntero nombre con dos subindices pero sin []
  117.         fila=2, col=1; // en base cero
  118.         int p8mat_fila3col2 =  ptrMatrixA[ ( fila * cols ) + col ];
  119.         // No se puede con el nombre la matrix , requiere ser el nombre del puntero // int p8mat_fila3col2 = matrixA[ (fila*cols) + col ]
  120.         cout << "\nMat: (fila2,col2) = " << p8mat_fila3col2 << endl; // 4
  121.        
  122.         int p5vec_col2 = *( vector + 1 );
  123.         cout << "\nVec: (col2) = " << p5vec_col2 << endl; // 8
  124.        
  125.         int p6vec_col3 = *( vector + 2 );
  126.         cout << "\nVec: (col3) = " << p6vec_col3 << endl; // 7
  127.        
  128.         // puntero hacia el inicio de cada fila
  129.         int p9mat_fila1 = *( matrixA [ 0 ] ); // muy interezante apunta al inicio de cada fila
  130.         cout << "\nMat: (fila1) = " << p9mat_fila1 << endl; // 1
  131.        
  132.         int p9mat_fila2 = *( matrixA [ 1 ] );  
  133.         cout << "\nMat: (fila2) = " << p9mat_fila2 << endl; // 3        
  134.        
  135.         int p9mat_fila3 = *( matrixA [ 2 ] );  
  136.         cout << "\nMat: (fila3) = " << p9mat_fila3 << endl; // 5       
  137.        
  138.         int p1matb_fila1 = *( matrixC [ 0 ] );  
  139.         cout << "\nMat: (fila1) = " << p1matb_fila1 << endl; // 1
  140.        
  141.         p1matb_fila1 = *( matrixC [ 1 ] );  
  142.         cout << "\nMat: (fila1) = " << p1matb_fila1 << endl; // 4
  143.        
  144.         p1matb_fila1 = *( matrixC [ 2 ] );  
  145.         cout << "\nMat: (fila1) = " << p1matb_fila1 << endl; // 7
  146.        
  147.         //////////////////////////////////////////////////////////////////
  148.        
  149.         int mat[ 2 ][ 3 ];// = { { 0, 1, 2 }, { 3, 4, 5 } };
  150.         load( &(mat[ 0 ][ 0 ]), 2, 3); // == load((int*)mat, 2, 3);
  151.         show( &(mat[ 0 ][ 0 ]), 2, 3);
  152.        
  153.         getchar();
  154.         return 0;
  155.        
  156.         system("PAUSE");  
  157.         return 0;
  158.        
  159. }
  160.  
  161. void load(int *pmat, char rows, char cols){
  162.         char c, r;
  163.         printf("\n");
  164.         for(r = 0; r < rows; r++)
  165.                 for(c = 0; c < cols; c++){
  166.                         pmat[ (r*cols) + c ] = (r*cols) + c;
  167.                 }
  168. }
  169.  
  170. //void show(int mat[][3], int rows, int cols){
  171.  
  172. void show(int *pmat, char rows, char cols){
  173.         char c, r;
  174.         printf("\n");
  175.         for(r = 0; r < rows; r++)
  176.                 for(c = 0; c < cols; c++){
  177.                         //printf("%d",   pmat[r][c]); //falla
  178.                         printf("%d ",*(pmat + r*cols + c));
  179.                         printf("%d ",  pmat[ (r*cols) + c ] );
  180.                 }
  181. }

Título: Re: alternativa manejo punteros a matrices bidimencionales
Publicado por: migsantiago en 21 de Mayo de 2014, 20:54:29
Hola

Esto falla...

Código: [Seleccionar]
int *ptrMatrix = &matrix[0][0];
Porque hay una gran diferencia entre una variable arreglo y una variable apuntador.

La variable arreglo conoce su tamaño por dimensión. La variable apuntador sólo apunta a una dirección, pero ella no sabe si esa dirección vive en un unidimensional, bidimensional, pentadimensional... o cualquier otro.

Cuando tú pides derreferenciar un apuntador con los [][], él no sabe cuánto mide cada dimensión y por eso no compila.

La respuesta es... un apuntador no puede calcular dimensiones. Debes definirlas tú.

Te propongo esto:

Código: [Seleccionar]
#define FILA 5
#define COLUMNA 10

#define MACRO_DERREF_BIDIM(apuntador, fila, columna) (apuntador + (fila * COLUMNA) + (columna))

int arreglo[FILA][COLUMNA]; /* Inicialízalo como gustes */
int* apuntador;

apuntador = &arreglo[3][2];

/* Derreferéncialo con estilo :D */
int entero = MACRO_DERREF_BIDIM(apuntador, 3, 2);

Saludos
Título: Re: alternativa manejo punteros a matrices bidimencionales
Publicado por: CompSystems en 26 de Mayo de 2014, 14:35:35
Gracias migsantiago

experimentando con mi código encontré que si se llama al nombre del arreglo con *(arrayName[pos]) apunta al inicio de cada fila, esto es de mucha utilidad para manipulación de imagenes  :-/


otra inquietud en la parte de mi código anexe un ejemplo que descargue de internet

como puede ver

Código: C++
  1. void show(int mat[][3], char rows, char cols);

esta comentado por que falla la compilacion, quien descubre por que

Código: C++
  1. void show(int *pmat char rows, char cols);
//compila satisfactoriamente, pero deseo ver la forma anterior

Gracias