sirven que punteros puntero para matriz los estructura ejemplo dinamica dev declaracion datos aritmetica apuntadores c++ pointers multidimensional-array

c++ - que - puntero a puntero



Conversión de matrices multidimensionales a punteros en c++ (7)

Como está utilizando C ++, la forma correcta de hacer algo como esto sería con una clase personalizada y algunas plantillas. El siguiente ejemplo es bastante difícil, pero tiene el punto básico.

#include <iostream> using namespace std; template <int matrix_size> class SquareMatrix { public: int size(void) { return matrix_size; } double array[matrix_size][matrix_size]; void copyInverse(const SquareMatrix<matrix_size> & src); void print(void); }; template <int matrix_size> void SquareMatrix<matrix_size>::copyInverse(const SquareMatrix<matrix_size> & src) { int inv_x; int inv_y; for (int x = 0; x < matrix_size; x++) { inv_x = matrix_size - 1 - x; for (int y = 0; y < matrix_size; y++) { inv_y = matrix_size - 1 - y; array[x][y] = src.array[inv_x][inv_y]; } } } template <int matrix_size> void SquareMatrix<matrix_size>::print(void) { for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { cout << array[x][y] << " "; } cout << endl; } } template <int matrix_size> void Initialize(SquareMatrix<matrix_size> & matrix); int main(int argc, char * argList[]) { SquareMatrix<4> startMatrix; SquareMatrix<4> inverseMatrix; Initialize(startMatrix); inverseMatrix.copyInverse(startMatrix); cout << "Start:" << endl; startMatrix.print(); cout << "Inverse:" << endl; inverseMatrix.print(); return 0; } template <int matrix_size> void Initialize(SquareMatrix<matrix_size> & matrix) { for (int x = 0; x < matrix_size; x++) { for (int y = 0; y < matrix_size; y++) { matrix.array[x][y] = (x+1)*10+(y+1); } } }

Tengo un programa que se parece a lo siguiente:

double[4][4] startMatrix; double[4][4] inverseMatrix; initialize(startMatrix) //this puts the information I want in startMatrix

Ahora quiero calcular el inverso de startMatrix y ponerlo en inverseMatrix. Tengo una función de biblioteca para este propósito cuyo prototipo es el siguiente:

void MatrixInversion(double** A, int order, double** B)

eso toma el inverso de A y lo coloca en B. El problema es que necesito saber cómo convertir el doble [4] [4] en un doble ** para darle a la función. Intenté simplemente hacerlo de la "manera obvia":

MatrixInversion((double**)startMatrix, 4, (double**)inverseMatrix))

pero eso no parece funcionar. ¿Es esa la forma correcta de hacerlo?


El problema es que una matriz bidimensional no es lo mismo que una matriz de punteros. Una matriz bidimensional almacena los elementos una fila tras otra, por lo tanto, cuando pasa una matriz de este tipo, solo se proporciona un puntero al inicio. La función de recepción puede encontrar la forma de encontrar cualquier elemento de la matriz, pero solo si conoce la longitud de cada fila .

Por lo tanto, su función de recepción debe declararse void MatrixInversion(double A[4][], int order, double B[4][]) .


La matriz bidimensional no es un puntero a puntero o algo similar. El tipo correcto para startMatrix es double (*)[4] . Para su función, la firma debería ser como:

MatrixInversion( double (*A)[4], int order, double (*B)[4] );


Por una razón dada que la matriz bidimensional (un bloque contiguo de memoria) y una matriz de punteros (no contiguos) son cosas muy diferentes, no se puede pasar una matriz bidimensional a una función que funcione con puntero a puntero.

Una cosa que podrías hacer: plantillas. Haga que el tamaño de la segunda dimensión sea un parámetro de plantilla.

#include <iostream> template <unsigned N> void print(double a[][N], unsigned order) { for (unsigned y = 0; y < order; ++y) { for (unsigned x = 0; x < N; ++x) { std::cout << a[y][x] << '' ''; } std::cout << ''/n''; } } int main() { double arr[3][3] = {{1, 2.3, 4}, {2.5, 5, -1.0}, {0, 1.1, 0}}; print(arr, 3); }

Otra manera, un poco más torpe, podría ser hacer que la función acepte un puntero a una matriz de una dimensión, y tanto el ancho como la altura proporcionados como argumentos, y calcular los índices en una representación bidimensional usted mismo.

#include <iostream> void print(double *a, unsigned height, unsigned width) { for (unsigned y = 0; y < height; ++y) { for (unsigned x = 0; x < width; ++x) { std::cout << a[y * width + x] << '' ''; } std::cout << ''/n''; } } int main() { double arr[3][3] = {{1, 2.3, 4}, {2.5, 5, -1.0}, {0, 1.1, 0}}; print(&arr[0][0], 3, 3); }

Naturalmente, una matriz es algo que merece una clase propia (pero lo anterior aún podría ser relevante, si necesita escribir funciones auxiliares).


por buena codificación si c ++:

struct matrix { double m[4][4]; }; matrix startMatrix; matrix inverseMatrix;

entonces la interfaz sería

void MatrixInversion(matrix &A, int order, matrix &B);

y usarlo

MatrixInversion(startMatrix, 4, inverseMatrix);

El beneficio

  1. la interfaz es muy simple y clara.
  2. una vez que necesite modificar "m" de la matriz internamente, no necesita actualizar la interfaz.

O de esta manera

struct matrix { void Inversion(matrix &inv, int order) {...} protected: double m[4][4]; }; matrix startMatrix; matrix inverseMatrix; ...

Una forma fea en c

void MatrixInversion(void *A, int order, void *B); MatrixInversion((void*)startMatrix, 4, (void*)inverseMatrix);

EDITAR: código de referencia para MatrixInversion que no se bloqueará:

void MatrixInversion(void *A, int order, void *B) { double _a[4][4]; double _b[4][4]; memcpy(_a, A, sizeof _a); memcpy(_b, B, sizeof _b); // processing data here // copy back after done memcpy(B, _b, sizeof _b); }


No, no hay una forma correcta de hacerlo específicamente. Una matriz double[4][4] no es convertible a un double ** puntero. Estas son dos maneras alternativas e incompatibles de implementar una matriz 2D. Algo necesita ser cambiado: ya sea la interfaz de la función o la estructura de la matriz pasada como un argumento.

La forma más simple de hacer esto último, es decir, hacer que su matriz existente double[4][4] compatible con la función, es crear matrices "indexadas" temporales de tipo double *[4] apuntando al comienzo de cada fila en cada una matriz

double *startRows[4] = { startMatrix[0], startMatrix[1], startMatrix[2] , startMatrix[3] }; double *inverseRows[4] = { /* same thing here */ };

y pasar estas matrices de "índice" en su lugar

MatrixInversion(startRows, 4, inverseRows);

Una vez que la función haya finalizado, puede olvidarse de las matrices startRows e inverseRows , ya que el resultado se colocará correctamente en su matriz inverseMatrix original.


Hay una solución que usa el puntero para señalar por bobobobo

William Sherif (bobobobo) usó la versión C y solo quiero mostrar la versión en C ++ de la respuesta de bobobobo.

int numRows = 16 ; int numCols = 5 ; int **a ; a = new int*[ numRows* sizeof(int*) ]; for( int row = 0 ; row < numRows ; row++ ) { a[row] = new int[ numCols*sizeof(int) ]; }

El resto del código es lo mismo con bobobobo''s.