c++ - matrices - Matriz bidimensional dinámica de puntero a puntero
punteros c++ (4)
El primer método no se puede usar para crear matrices 2D dinámicas porque al hacerlo:
int *board[4];
esencialmente asignó una matriz de 4 punteros a int
en la pila . Por lo tanto, si ahora llena cada uno de estos 4 punteros con una matriz dinámica:
for (int i = 0; i < 4; ++i) {
board[i] = new int[10];
}
con lo que termina es una matriz 2D con número estático de filas (en este caso 4) y número dinámico de columnas (en este caso 10). Por lo tanto, no es completamente dinámico porque cuando asigna una matriz en la pila debe especificar un tamaño constante , es decir, conocido en tiempo de compilación . La matriz dinámica se denomina dinámica porque no es necesario conocer su tamaño en tiempo de compilación , pero puede ser determinado por alguna variable en tiempo de ejecución .
Una vez más, cuando lo haces:
int *board[4];
o:
const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];
usted suministra una constante conocida en tiempo de compilación (en este caso 4 o x
) para que el compilador pueda preasignar esta memoria para su matriz, y cuando su programa se carga en la memoria ya tendría esta cantidad de memoria para el board
matriz, es por eso que se llama estática , es decir, porque el tamaño está codificado y no se puede cambiar dinámicamente (en tiempo de ejecución).
Por otro lado, cuando lo haces:
int **board;
board = new int*[10];
o:
int x = 10; // <--- Notice that it does not have to be `const` anymore!
int **board;
board = new int*[x];
el compilador no sabe cuánto requerirá la matriz de la board
memoria y, por lo tanto, no asigna previamente nada. Pero cuando inicie su programa, el tamaño de la matriz estará determinado por el valor de la variable x
(en tiempo de ejecución) y el espacio correspondiente para la matriz de la board
se asignará en el denominado montón , el área de memoria donde todos los programas que se ejecutan en su la computadora puede asignar memoria previa desconocida (en tiempo de compilación) para uso personal.
Como resultado, para crear realmente una matriz dinámica en 2D tienes que ir con el segundo método:
int **board;
board = new int*[10]; // dynamic array (size 10) of pointers to int
for (int i = 0; i < 10; ++i) {
board[i] = new int[10];
// each i-th pointer is now pointing to dynamic array (size 10) of actual int values
}
Acabamos de crear una matriz cuadrada 2D con 10 por 10 dimensiones. Para recorrerlo y poblarlo con valores reales, por ejemplo 1, podríamos usar bucles anidados:
for (int i = 0; i < 10; ++i) { // for each row
for (int j = 0; j < 10; ++j) { // for each column
board[i][j] = 1;
}
}
Primer contador de tiempo en este sitio web, así que aquí va ...
Soy un novato en C ++ y actualmente estoy trabajando en el libro "Estructuras de datos usando C ++ 2nd ed, de DS Malik".
En el libro, Malik ofrece dos formas de crear una matriz bidimensional dinámica. En el primer método, declaras que una variable es una matriz de punteros, donde cada puntero es de tipo entero. ex.
int *board[4];
..y luego use un for-loop para crear las ''columnas'' mientras utiliza la matriz de punteros como ''filas''.
El segundo método, usa un puntero a un puntero.
int **board;
board = new int* [10];
etc.
Mi pregunta es esta: ¿cuál es el mejor método? El método ** es más fácil de visualizar, pero el primer método se puede usar de la misma manera. Ambas formas se pueden usar para crear matrices dinámicas de 2 d.
Editar: No fue lo suficientemente claro con la publicación anterior. Aquí hay un código que probé:
int row, col;
cout << "Enter row size:";
cin >> row;
cout << "/ncol:";
cin >> col;
int *p_board[row];
for (int i=0; i < row; i++)
p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_board[i][j] = j;
cout << p_board[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
p_p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_p_board[i][j] = j;
cout << p_p_board[i][j] << " ";
}
cout << endl;
}
En ambos casos, su dimensión interna puede ser especificada dinámicamente (es decir, tomada de una variable), pero la diferencia está en la dimensión externa.
Esta pregunta es básicamente equivalente a lo siguiente:
Es
int* x = new int[4];
"mejor" queint x[4]
?
La respuesta es: " no , a menos que tenga que elegir esa dimensión de matriz dinámicamente".
Este código funciona bien con muy pocos requisitos en bibliotecas externas y muestra un uso básico de int **array
.
Esta respuesta muestra que cada matriz tiene un tamaño dinámico, así como también la forma de asignar una matriz de hojas de tamaño dinámico a la matriz de ramas de tamaño dinámico.
Este programa toma argumentos de STDIN en el siguiente formato:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Código para el programa a continuación ...
#include <iostream>
int main()
{
int **array_of_arrays;
int num_arrays, num_queries;
num_arrays = num_queries = 0;
std::cin >> num_arrays >> num_queries;
//std::cout << num_arrays << " " << num_queries;
//Process the Arrays
array_of_arrays = new int*[num_arrays];
int size_current_array = 0;
for (int i = 0; i < num_arrays; i++)
{
std::cin >> size_current_array;
int *tmp_array = new int[size_current_array];
for (int j = 0; j < size_current_array; j++)
{
int tmp = 0;
std::cin >> tmp;
tmp_array[j] = tmp;
}
array_of_arrays[i] = tmp_array;
}
//Process the Queries
int x, y;
x = y = 0;
for (int q = 0; q < num_queries; q++)
{
std::cin >> x >> y;
//std::cout << "Current x & y: " << x << ", " << y << "/n";
std::cout << array_of_arrays[x][y] << "/n";
}
return 0;
}
Es una implementación muy simple de int main
y se basa únicamente en std::cin
y std::cout
. Barebones, pero lo suficientemente bueno como para mostrar cómo trabajar con arreglos multidimensionales simples.
Lo que describes para el segundo método solo te da una matriz 1D:
int *board = new int[10];
Esto solo asigna una matriz con 10 elementos. Quizás quisiste decir algo como esto:
int **board = new int*[4];
for (int i = 0; i < 4; i++) {
board[i] = new int[10];
}
En este caso, asignamos 4 int*
sy luego hacemos que cada uno de ellos apunte a una matriz dinámicamente asignada de 10 int
s.
Entonces ahora estamos comparando eso con int* board[4];
. La principal diferencia es que cuando utiliza una matriz como esta, debe conocerse el número de "filas" en tiempo de compilación. Esto se debe a que las matrices deben tener tamaños fijos en tiempo de compilación. También puede tener un problema si desea quizás devolver esta matriz de int*
s, ya que la matriz se destruirá al final de su alcance.
El método donde tanto las filas como las columnas se asignan dinámicamente requiere medidas más complicadas para evitar fugas de memoria. Debes desasignar la memoria así:
for (int i = 0; i < 4; i++) {
delete[] board[i];
}
delete[] board;
Debo recomendar el uso de un contenedor estándar en su lugar. Puede usar std::array<int, std::array<int, 10> 4>
o quizás un std::vector<std::vector<int>>
que inicie con el tamaño apropiado.