Vejamos o seguinte exemplo:
Essas 3 matrizes 1D podem ser representadas como uma matriz 2D da seguinte forma:
Vamos ver outro exemplo:
Essas matrizes 3 1D não podem ser representadas como uma matriz 2D porque os tamanhos das matrizes são diferentes.
Declaração de array 2D
tipo de dados nome-array[FILA] [COL]
- Tipo de dados é o tipo de dados dos elementos da matriz.
- Array-name é o nome do array.
- Dois subscritos representam o número de linhas e colunas da matriz. O número total de elementos da matriz será ROW * COL.
int a [2] [3];
Usando o código C acima, podemos declarar um inteiro variedade, uma do tamanho 2 * 3 (2 linhas e 3 colunas).
char b [3] [2];
Usando o código C acima, podemos declarar um personagem variedade, b do tamanho 2 * 3 (3 linhas e 2 colunas).
Inicialização de matriz 2D
Podemos inicializar durante a declaração das seguintes maneiras:
- int a [3] [2] = 1,2,3,4,5,6;
- int a [] [2] = 1,2,3,4,5,6;
- int a [3] [2] = 1, 2, 3, 4, 5, 6;
- int a [] [2] = 1, 2, 3, 4, 5, 6;
Observe que em 2 e 4 não mencionamos o 1st subscrito. O compilador C calcula automaticamente o número de linhas a partir do número de elementos. Mas os 2WL o subscrito deve ser especificado. As seguintes inicializações são inválidas:
- int a [3] [] = 1,2,3,4,5,6;
- int a [] [] = 1,2,3,4,5,6;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | //Exemplo 1.c #incluir #define LINHA 3 #define COL 2 int main () int i, j; int a [ROW] [COL] = 1,2, 3,4, 5,6 ; printf ("Os elementos do array a são: \ n"); para (i = 0; i printf ("Linha% d:", i); para (j = 0; j printf ("% d", a [i] [j]); printf ("\ n"); printf ("\ n \ nElementos das colunas do array a são: \ n"); para (i = 0; i printf ("Coluna% d:", i); para (j = 0; j printf ("% d", a [j] [i]); printf ("\ n"); return 0; |
No Exemplo 1.c, declaramos uma matriz inteira de tamanho 3 * 2 e inicializamos. Para acessar os elementos do array, usamos dois for loop.
Para acessar a linha, o loop externo é para linhas e o loop interno é para colunas.
Para acessar as colunas, o loop externo é para colunas e o loop interno é para linhas.
Observe que quando declaramos uma matriz 2D, usamos a [2] [3], o que significa 2 linhas e 3 colunas. A indexação da matriz começa em 0. Para acessar o 2WL linha e 3rd coluna, temos que usar a notação a [1] [2].
Mapeamento de memória de uma matriz 2D
A visão lógica de um array a [3] [2] pode ser o seguinte:
A memória do computador é uma sequência 1D de bytes. Na linguagem C, uma matriz 2D é armazenada na memória em ordem principal de linha. Algumas outras linguagens de programação (e.g., FORTRAN), ele armazena em ordem da coluna principal na memória.
Pointer Aritmética de uma matriz 2D
Para entender a aritmética do ponteiro da matriz 2D, primeiro, dê uma olhada na matriz 1D.
Considere uma matriz 1D:
Na matriz 1D, uma é uma constante e seu valor é o endereço do 0º localização da matriz a [5]. Valor de a + 1 é o endereço do 1st localização da matriz a [5]. a + i é o endereço do euº localização da matriz.
Se incrementarmos uma em 1, é incrementado pelo tamanho do tipo de dados.
a [1] é equivalente a * (a + 1)
a [2] é equivalente a * (a + 2)
a [i] é equivalente a * (a + i)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // Exemplo2.c #incluir #define LINHA 3 #define COL 2 int main () int a [5] = 10,20,30,40,50; printf ("sizeof (int):% ld \ n \ n", sizeof (int)); printf ("a:% p \ n", a); printf ("a + 1:% p \ n", a + 1); printf ("a + 2:% p \ n \ n", a + 2); printf ("a [1]:% d, * (a + 1):% d \ n", a [1], * (a + 1)); printf ("a [2]:% d, * (a + 2):% d \ n", a [1], * (a + 1)); printf ("a [3]:% d, * (a + 3):% d \ n", a [1], * (a + 1)); return 0; |
No Exemplo 2.c, o endereço de memória está sendo exibido em hexadecimal. A diferença entre a e a + 1 é 4, que é o tamanho de um inteiro em bytes.
Agora, considere uma matriz 2D:
b é um ponteiro do tipo: int [] [4] ou int (*) [4]
int [] [4] é uma linha de 4 inteiros. Se incrementarmos b por 1, ele é incrementado pelo tamanho da linha.
b é o endereço do 0º fila.
b + 1 é o endereço do 1st fila.
b + i é o endereço de euº fila.
O tamanho de uma linha é: (Número da coluna * sizeof (tipo de dados)) bytes
O tamanho de uma linha de uma matriz de inteiros b [3] [4] é: 4 * sizeof (int) = 4 * 4 = 16 bytes
Uma linha de uma matriz 2D pode ser vista como uma matriz 1D. b é o endereço do 0º fila. Então, temos o seguinte
- * b + 1 é o endereço do 1st elemento do 0º
- * b + j é o endereço do jº elemento do 0º
- * (b + i) é o endereço do 0º elemento do euº
- * (b + i) + j é o endereço do jº elemento do euº
- b [0] [0] é equivalente a ** b
- b [0] [1] é equivalente a * (* b + 1)
- b [1] [0] é equivalente a * (* (b + 1))
- b [1] [1] é equivalente a * (* (b + 1) +1)
- b [i] [j] é equivalente a * (* (b + i) + j)
Endereço de b [i] [j]: b + sizeof (tipo de dados) * (Número da coluna * i + j)
Considere uma matriz 2D: int b [3] [4]
Endereço de b [2] [1] é : b + sizeof (int) * (4 * 2 + 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // Exemplo3.c #incluir #define LINHA 3 #define COL 4 int main () int i, j; int b [ROW] [COL] = 10,20,30,40, 50,60,70,80, 90.100.110.120 ; printf ("sizeof (int):% ld \ n", sizeof (int)); printf ("Tamanho de uma linha:% ld \ n", COL * sizeof (int)); printf ("b:% p \ n", b); printf ("b + 1:% p \ n", b + 1); printf ("b + 2:% p \ n", b + 2); printf ("* b:% p \ n", * b); printf ("* b + 1:% p \ n", * b + 1); printf ("* b + 2:% p \ n", * b + 2); printf ("b [0] [0]:% d ** b:% d \ n", b [0] [0], ** b); printf ("b [0] [1]:% d * (* b + 1):% d \ n", b [0] [1], * (* b + 1)); printf ("b [0] [2]:% d * (* b + 2):% d \ n", b [0] [2], * (* b + 2)); printf ("b [1] [0]:% d * (* (b + 1)):% d \ n", b [1] [0], * (* (b + 1))); printf ("b [1] [1]:% d * (* (b + 1) +1):% d \ n", b [1] [1], * (* (b + 1) +1) ); return 0; |
No Exemplo 3.c, vimos que o tamanho de uma linha é 16 em notação decimal. A diferença entre b + 1 e b é 10 em hexadecimal. 10 em hexadecimal é equivalente a 16 em decimal.
Conclusão
Então, neste artigo, aprendemos sobre
- Declaração de array 2D
- Inicialização de matriz 2D
- Mapeamento de memória de matriz 2D
- Pointer Aritmética de matriz 2D
Agora podemos usar array 2D em nosso programa C sem qualquer dúvida,
Referências
Os créditos para algumas ideias neste trabalho foram inspirados no curso Pointers and 2-D Arrays, do Palash Dey Department of Computer Science & Engg. Instituto Indiano de Tecnologia Kharagpur