Extracting a 3x3 chunk from a 10x10 matrix and passing it to a function has some complications. The first is that in matrices, all elements are stored in memory sequentially. That is, in a 10x10 matrix we have the 100 elements in sequence. In a 3x3 matrix, we will have the 9 elements in sequence. However, in a 3x3 matrix within a 10x10, the 9 desired 3x3 elements will not be in sequence, and therefore cannot be simply represented in the form of a simple pointer, which requires a more elaborate technique.
In addition, there are still some problems regarding that the processing of a submatrix may end up interfering in the processing of another submatrix when the matrix elements are changed. For example, imagine you have the following matrix (I will use 5x5 to make it easier to understand):
A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y
If when processing the ABC-FGH-KLM submarine, you replace the G with a Z, the subsequent submarine will be BCD-ZHI-LMN instead of BCD-GHI-LMN.
There are several possible solutions to this problem. I think the simplest solution to this problem would be:
Represent the submatrix as main matrix indices.
Use two different matrices, one for data reading and one for draft for writing. At the end, the draft matrix can be copied over the original and then discarded, or else the original be discarded and keep the resulting.
If I understand correctly, you want a function that receives another function as a parameter in order to apply it over the whole matrix. In object-oriented programming languages and with generic types such as C++ and Java, this is much easier to do. This is also possible in C, but with scary syntax. Here’s the result:
#include <stdio.h>
void conv(int largura, int altura, int linha, int coluna, int original[altura][largura], int resultante[altura][largura]) {
int i, j;
if (linha >= altura - 2 || coluna >= largura - 2) return;
for (i = linha; i < linha + 3; i++) {
for (j = coluna; j < coluna + 3; j++) {
resultante[i][j] = original[i][j] * original[i][j];
}
}
}
void operar(int largura, int altura, int original[altura][largura], int resultante[altura][largura], void (*op)(int largura, int altura, int linha, int coluna, int original[largura][altura], int resultante[altura][largura])) {
int i, j;
for (i = 0; i < altura; i++) {
for (j = 0; j < largura; j++) {
op(largura, altura, i, j, original, resultante);
}
}
}
void imprimir(int largura, int altura, int original[altura][largura]) {
int i, j;
for (i = 0; i < altura; i++) {
for (j = 0; j < largura; j++) {
printf("%5d ", original[i][j]);
}
printf("\n");
}
}
int main() {
int entrada[5][5] = {{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}};
int saida[5][5];
operar(5, 5, entrada, saida, conv);
imprimir(5, 5, entrada);
printf("\n");
imprimir(5, 5, saida);
}
See here working on ideone. Here is the output generated:
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
1 4 9 16 25
36 49 64 81 100
121 144 169 196 225
256 289 324 361 400
441 484 529 576 625
Note that the function conv
It’s almost the same as what you gave. The difference is that the width and height of the matrix are explained in the function parameters as well as the row and column of the 3x3 block to be operated. There are also two matrices, one of which will be read and the other of which will be written.
The function operar
is the scariest and has a horribly long and complicated signature. In particular the void (*op)(int largura, int altura, int linha, int coluna, int original[largura][altura], int resultante[altura][largura])
is a function pointer. The void
is the return type of the function. The (*op)
indicates that this is a function pointer called op
and the content after that corresponds to the types of parameters of that function. The code within the function operar
however it is quite simple, it just runs through the matrices calling the function op
in all positions.
Finally, in the function main
we have it:
operar(5, 5, entrada, saida, conv);
This means that the function conv
shall be executed for each position of 5x5 matrices entrada
and saida
. This way, you can encode other functions similar to conv
, provided they have the same parameters and return void
and use it in function operar
likewise.
Ah, and an important observation. That only makes sense if you really need submarines in your role conv
or similar. If you are working element by element without the processing of one element interfering with the other, all this would be much simpler. At the moment, its function conv
could be rewritten like this:
void conv(int largura, int altura, int linha, int coluna, int original[altura][largura], int resultante[altura][largura]) {
resultante[linha][coluna] = original[linha][coluna] * original[linha][coluna];
}
Set "belongs to the matrix" and "run inside the other one", please.
– Woss
Example: this is matrix 3x3: void convulacao(int p[3][3]){ int i, j; for(i=0;i<3;i++){ for(j=0;j<3;j++){ p[i][j]=p[i][j]*p[i][j];
 }
 } }
– Sbim
Just below the question, there is the button
editar
. Use it to post the codes you wrote. It will be easier to understand the problem.– Woss
p[i][j]=p[i][j]*p[i][j];
- this will only replace each element of the matrix by the value of its square.– Victor Stafusa
I don’t know if I got it right. Going through a 10x10 matrix and extracting 3x3 pieces is easy. But what do you want to do with these 3x3 pieces?
– Victor Stafusa
Okay, I think I get it. I’m going to try to formulate an answer.
– Victor Stafusa
I edited the question.. actually it’s a bit of extensive code, I really needed to make one matrix run inside the other.. I only abbreviated the code to make it easier..
– Sbim