Alocação dinâmica de matrizes
Para entendermos a alocação dinâmica de matrizes, precisamos relembrar que matrizes são armazenadas como vetores de vetores. Para não ser redundante, é importante lembrar que os princípios aplicáveis aos vetores (como a realocação em tempo de execução) são aplicáveis também às matrizes.
Há, entretanto, algumas particularidades. Antes de prosseguirmos, vamos relembrar a declaração tradicional de matriz, que tem o seguinte padrão:
int matriz[qtdeLinhas][qtdeColunas];
Na alocação dinâmica de matriz, temos dois caminhos distintos.
1️⃣ Caso 1: Matriz como vetor
A primeira possibilidade para se trabalhar com matrizes de forma dinâmica envolve declará-la como um grande vetor:
int *matriz = (int*)calloc(qtdeLinhas*qtdeColunas, sizeof(int));
Em uma matriz 2x2
, poderíamos acessar suas posições da seguinte forma:
#include <stdio.h>
#include<stdlib.h>
int main()
{
int qtdeLinhas = 2;
int qtdeColunas = 2;
int *matriz = (int*)calloc(qtdeLinhas*qtdeColunas, sizeof(int));
matriz[0] = 7;
matriz[1] = 14;
matriz[2] = 21;
matriz[3] = 28;
return 0;
}
Todavia, toda a representação de matriz deixaria de fazer sentido. Para contornar essa situação, temos algumas estratégias.
Percorrendo a matriz
Para percorrer uma matriz usando colchetes, temos a seguinte possibilidade:
matriz[linhaDesejada * qtdeColunas + colunaDesejada];
Vamos lá:
#include <stdio.h>
#include<stdlib.h>
int main()
{
int qtdeLinhas = 2;
int qtdeColunas = 2;
int *matriz = (int*)calloc(qtdeLinhas*qtdeColunas, sizeof(int));
/* Para preencher */
for(int i = 0; i < qtdeLinhas; i++){
for(int j = 0; j < qtdeColunas; j++){
matriz[i * qtdeColunas + j] = rand() % 10;
}
}
/* Para imprimir */
for(int i = 0; i < qtdeLinhas; i++){
for(int j = 0; j < qtdeColunas; j++){
printf("%d ", matriz[i * qtdeColunas + j]);
}
printf("\n");
}
return 0;
}
2️⃣ Caso 2: Matriz como um vetor de vetores
A segunda estratégia pode ser um pouco mais familiar. Ela envolve considerar a matriz como um ponteiro duplo, tornando a sua representação muito próxima daquilo que vimos quando estudamos aritmética de ponteiros em matrizes:
int **matriz = (int**)calloc(nroDeLinhas, sizeof(int*));
Depois, precisamos criar os vetores que representam as colunas, com a seguinte operação:
matriz[numeroDaLinha] = (int*)calloc(qtdeColunas, sizeof(int));
Agora, vamos ao código completo:
#include <stdio.h>
#include<stdlib.h>
int main()
{
int qtdeLinhas = 2;
int qtdeColunas = 2;
int **matriz = (int**)calloc(qtdeLinhas, sizeof(int*));
/* Criar colunas */
for(int i = 0; i<qtdeLinhas; i++){
matriz[i] = (int*)calloc(qtdeColunas, sizeof(int));
}
/* Percorrer com aritmética */
for(int i = 0; i<qtdeLinhas; i++){
for(int j = 0; j<qtdeColunas; j++){
*(*(matriz+i)+j) = rand() % 10;
}
}
/* Imprimir com colchete */
for(int i = 0; i<qtdeLinhas; i++){
for(int j = 0; j<qtdeColunas; j++){
printf("%d ", matriz[i][j]);
}
printf("\n");
}
/* Liberar a memória */
for(int i = 0; i < qtdeLinhas; i++) {
free(matriz[i]);
}
free(matriz);
return 0;
}
📦 Mudando o tamanho da matriz
Assim como com vetores, podemos realocar o tamanho da matriz, aumentando sua quantidade de linhas e colunas.
Adicionando linhas
Para realocar a quantidade de linhas da matriz, podemos usar o seguinte código:
int totalLinhas = 4; // qtdeLinhas + novas
matriz = (int**)realloc(matriz, totalLinhas * sizeof(int*));
// Alocar e inicializar as novas linhas
for(int i = qtdeLinhas; i < totalLinhas; i++) {
matriz[i] = (int*)calloc(qtdeColunas, sizeof(int));
for(int j = 0; j < qtdeColunas; j++) {
matriz[i][j] = 0;
}
}
qtdeLinhas = totalLinhas;
Adicionando colunas
Para realocar a quantidade de colunas da matriz, podemos usar o seguinte código:
int totalColunas = 4; // qtdeColunas + novas
for(int i = 0; i < qtdeLinhas; i++) {
matriz[i] = (int*)realloc(matriz[i], totalColunas * sizeof(int));
for(int j = qtdeColunas; j < totalColunas; j++) {
matriz[i][j] = 0;
}
}
qtdeColunas = totalColunas;
📖 Bibliografia
Livros
- Backes, A. (2018). Linguagem C - Completa e Descomplicada.