How do one array run inside another using functions?

1

I have two functions, one belongs to a 10x10 array and the other to a 3x3 array. I need to make the 3x3 array run within the 10x10 array.

How do I do this?

Thank you in advance for your help.

Example: this is the 3x3 array:

void conv(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];
        }
    }
}

void img(int mat[lin][col]){
    int i, j, contador=1;
    for(i=0;i<lin;i++){
        for(j=0;j<col;j++){

        }
    }
}

I need the conv function, which has an array, to be inserted into the img function, where there is another array. I need it to cycle through all elements of the img array by changing the original value.

    
asked by anonymous 19.02.2017 / 21:26

1 answer

1

Extracting a 3x3 excerpt from a 10x10 array and passing it to a function has some complications. The first is that in arrays, 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 elements of the 3x3 will not be in sequence, and therefore can not simply be represented in the form of a simple pointer, which requires a more elaborate technique.

In addition, there are still some problems concerning the processing of one submatrix may end up interfering with the processing of another submatrix when the array elements are changed. For example, imagine that you have the following matrix (I'll 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 you process sub-matrix ABC-FGH-KLM, you replace G with a Z, the subsequent sub-matrix will be BCD- Z HI-LMN instead of BCD- G HI-LMN.

There are several possible workarounds for this problem. I think the simplest solution to this problem would be:

  • Represent the sub-matrix as indexes of the main matrix.

  • Use two different arrays, one for reading data and one for writing. At the end, the sketch matrix can be copied over the original and then discarded, or else the original can be discarded and the resultant remain.

If I get it right, you want a function that gets another function as a parameter in order to apply it over the entire array. In object-oriented programming languages with generic types such as C ++ and Java, this is much easier to do. This is also possible in 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);
}

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 conv function is almost the same as you gave it. 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 arrays, one to be read and one to write.

The operar function is the most frightening and has a horrendously 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. void is the return type of the function. The (*op) indicates that this is a function pointer named op , and the contents thereafter correspond to the parameter types of that function. The code inside the operar function is very simple, however, it only traverses the arrays by calling the op function in all positions.

Finally, in the function main we have this:

operar(5, 5, entrada, saida, conv);

This means that the conv function must be executed for each position of the arrays 5x5 entrada and saida . In this way, you can code other functions similar to the conv , as long as they have the same parameters and the void return and use it in the operar function in the same way.

Oh, and one important note. This only makes sense if you really need submatrices in your conv or similar function. If you are working element by element without processing one element to interfere in the other, all this would be much simpler. At the moment, its conv function 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];
}
    
19.02.2017 / 23:25