c – pass array as pointer

Question:

I need to make the proposal:

Create a function that receives as parameters a matrix pointer, the number of rows and columns, and prints the matrix elements.

But I'm learning pointers and having difficulties, I've tried in several ways to pass the array pointer but it gives an error anyway. Now the error is on the line:

            printf("\t%d",*mtr[lin][col]);
[Error] invalid types 'int* (*)[4][int*]' for array subscript

Here's my code:

#include <stdio.h>
#include <stdlib.h>

int matriz_ponteiro(int *mtr[3][4], int *lin, int *col){
    // imprimir a matriz
    for (*lin=0; *lin<3; *lin++){
        printf("\n");
        for (*col=0; *col<4; *col++){
            printf("\t%d",*mtr[lin][col]);
        }   
    }
    return *mtr[lin][col];

}


int main (){
    int res, mtr [3][4];
    int lin, col, cont;
    cont = 0;
    // armazenar o valor de cont em cada posição da matriz
    for (lin=0; lin<3; lin++){
        for (col=0; col<4; col++){
            mtr[lin][col]= cont++;
        }
    }
    res = matriz_ponteiro(mtr[3][4], lin, col);
}

Answer:

I understand the code – first alternative

Look at this line:

matriz_ponteiro(mtr[3][4], lin, col);

lin and col are of type int . mtr is a 3×4 array of type int , so mtr[3] is a 4-position array of type int and finally mtr[3][4] is an int . That is, the three parameters you pass are int s.

In the function definition, we have this:

int matriz_ponteiro(int *mtr[3][4], int *lin, int *col){

That is, the parameters are of the types " pointer to int 3×4 array ", " pointer to int " and " pointer to int ". In other words, they don't match what you use to call lower.

Well, in your code you mix arrays, pointers and integers more or less randomly, which shows that you may not really know what you're doing, so let's take it easy. Apparently, the purpose of your matriz_ponteiro function is to print the array. So here's its header:

void matriz_ponteiro(int mtr[3][4])

Why? Because it takes a 3×4 array of integers to print ( int mtr[3][4] and returns no result ( void ).

It doesn't need the lin and col parameters because it will traverse all the rows and columns. Therefore, the implementation is like this:

void matriz_ponteiro(int mtr[3][4]) {
    int lin, col;
    for (lin = 0; lin < 3; lin++) {
        printf("\n");
        for (col = 0; col < 4; col++) {
            printf("\t%d", mtr[lin][col]);
        }
    }
}

And with that, in your main , instead:

res = matriz_ponteiro(mtr[3][4], lin, col);

Use isso:

matriz_ponteiro(mtr);

And you can also drop the res variable.

Here's what your complete code looks like:

#include <stdio.h>
#include <stdlib.h>

void matriz_ponteiro(int mtr[3][4]) {
    int lin, col;
    for (lin = 0; lin < 3; lin++) {
        printf("\n");
        for (col = 0; col < 4; col++) {
            printf("\t%d", mtr[lin][col]);
        }
    }
}

int main() {
    int mtr[3][4];
    int lin, col, cont;
    cont = 0;
    // armazenar o valor de cont em cada posição da matriz
    for (lin = 0; lin < 3; lin++) {
        for (col = 0; col < 4; col++) {
            mtr[lin][col]= cont++;
        }

    }
    matriz_ponteiro(mtr);
}

See here working on ideone.

second alternative

If you have to have the number of rows and columns as a parameter, you can do this:

#include <stdio.h>
#include <stdlib.h>

void matriz_ponteiro(int linhas, int colunas, int matriz[linhas][colunas]) {
    int lin, col;
    for (lin = 0; lin < linhas; lin++) {
        for (col = 0; col < colunas; col++) {
            printf("\t%d", matriz[lin][col]);
        }
        printf("\n");
    }
}

int main() {
    int mtr[3][4];
    int lin, col, cont;
    cont = 0;
    // armazenar o valor de cont em cada posição da matriz
    for (lin = 0; lin < 3; lin++) {
        for (col = 0; col < 4; col++) {
            mtr[lin][col] = cont++;
        }
    }
    matriz_ponteiro(3, 4, mtr);
}

See here working on ideone. It is important to note that the matrix has to be the last parameter, as its definition depends on the number of rows and columns that have to be declared before (ie in the previous parameters).

The array used there is a pointer. To prove this, try putting this at the end of the matriz_ponteiro function:

    mtr[0][0] = 1234;

And at the end of main , use this twice:

    matriz_ponteiro(3, 4, mtr);

And you will notice that the array actually changes from within the matriz_ponteiro . If it were just copied, the 1234 wouldn't show up when calling the matriz_ponteiro function again. This is only possible because a reference pass occurred, not just values. And if there was a passing of a reference in C, it is because there was a passing of a pointer.

third alternative

However, if you want the matriz_ponteiro function to receive an explicit pointer, then you can do it like this:

#include <stdio.h>
#include <stdlib.h>

void matriz_ponteiro(int *matriz, int linhas, int colunas) {
    int lin, col;
    for (lin = 0; lin < linhas; lin++) {
        if (lin != 0) printf("\n");
        for (col = 0; col < colunas; col++) {
            printf("\t%d", matriz[lin * colunas + col]);
        }
    }
}

int main() {
    int mtr[3][4];
    int lin, col, cont;
    cont = 0;
    // armazenar o valor de cont em cada posição da matriz
    for (lin = 0; lin < 3; lin++) {
        for (col = 0; col < 4; col++) {
            mtr[lin][col] = cont++;
        }

    }
    matriz_ponteiro(mtr[0], 3, 4);
}

See working on ideone.

This matriz[lin * colunas + col] needs a better explanation. What happens is that the elements of the array are placed in the form of one row after another. That is, the matrix consists of a sequence of rows and each row has a number of elements equal to the number of columns. This can also be interpreted as an array with linhas * colunas elements. This formula lin * colunas + col accesses the desired element if you are using this form of indexing.

The use of mtr[0] at the end is because the type must be an int * , not an int ** . Another way would be to do an explicit cast as well (use (int *) mtr ).

Scroll to Top