A
Extracting a 3x3 excerpt 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 matrix 10x10 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 elements of 3x3 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 related problems that processing a submatrix may end up interfering in processing 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 by processing the ABC-FGH-KLM submatrix, you replace the G with a Z, the subsequent submatrix 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 indexes of the main matrix.Use two different matrices, one for data reading and another draft for writing. In the end, the draft matrix can be copied over the original and then discarded, or else the original is discarded and remain the resultant.If I understood right, you want a function that receives another function as a parameter in order to apply it over the entire matrix. In object-oriented programming languages and generic types such as C++ and Java, this is much easier to do. This is also possible in the C, but with a frightening 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);
}
http://ideone.com/dNnj0a Here is the generated output: 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 you did. 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 being read and one where it will be written.The function operar is the scariest and has a horrifyingly long and complicated signature. In particular void (*op)(int largura, int altura, int linha, int coluna, int original[largura][altura], int resultante[altura][largura]) is a function pointer. O void is the type of return of the function. O (*op) indicates that this is a function pointer called op and the content after that corresponds to the parameters of this function. The code inside the function operar however it is quite simple, it only goes through the matrices calling the function op in all positions.Finally, in the function main We have this:operar(5, 5, entrada, saida, conv);
This means that the function conv must be executed for each position of 5x5 arrays entrada and saida. In this way, you can encode other functions similar to that of conv, provided they have the same parameters and the return void and use it in the function operar like this.Oh, and an important observation. This only makes sense if you really need submatrix in your function conv or similar. If you are working element by element without the processing of an element interfering in 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];
}