0

I'm new to C and I'm learning pointers. So, I want to pass the pointer of a 2d array. I managed to make it work, but I still get the following warning:

||=== Build: Debug in matriz (compiler: GNU GCC Compiler) ===|
C:\Users\pauli\.dev\c\uvv\matriz\main.c||In function 'main':|
C:\Users\pauli\.dev\c\uvv\matriz\main.c|15|warning: passing argument 1 of 
'printMatriz' from incompatible pointer type [-Wincompatible-pointer-types]|
C:\Users\pauli\.dev\c\uvv\matriz\main.c|4|note: expected 'int * (*)[2]' but 
argument is of type 'int (*)[2][2]'|
C:\Users\pauli\.dev\c\uvv\matriz\main.c||In function 'printMatriz':|
C:\Users\pauli\.dev\c\uvv\matriz\main.c|23|warning: format '%i' expects argument 
of type 'int', but argument 2 has type 'int *' [-Wformat=]|
||=== Build finished: 0 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
||=== Run: Debug in matriz (compiler: GNU GCC Compiler) ===|

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#define TAM 2
void printMatriz(int *matriz[TAM][TAM]);

int main()
{
    int i, j, matriz[TAM][TAM];
    for(i = 0; i < TAM; i++) {
        for(j = 0; j < TAM; j++) {
            printf("Matriz[%i][%i] = ", i, j);
            scanf("%i", &matriz[i][j]);
        }
    }
    printMatriz(&matriz);
    return 0;
}
void printMatriz(int *matriz[TAM][TAM])
{
    int i, j;
    for(i = 0; i < TAM; i++) {
        for(j = 0; j < TAM; j++) {
            printf("%i\t", matriz[j][i]);
        }
        printf("\n");
    }
}
5
  • 1
    Why are you claiming that the function receives a matrix of int * values? Drop the * from the function prototype and definition. Commented Sep 12, 2018 at 1:02
  • See stackoverflow.com/questions/14808908/… to see how to define a pointer to a 2D array. In your printMatriz function you will also need to dereference the pointer to the array (add a * in front of matriz in the printf statement) . Commented Sep 12, 2018 at 1:10
  • int *matriz[][] in function declartion means 2D array of pointers to int. In 'main' you declared it as a 2D array of just int: int matriz[][]. These are inncompatible types. Remove the '*'. Commented Sep 12, 2018 at 1:36
  • i forgot to declare it as a pointer. Now that I did it, it keeps displaying the warning, here is the code now pastebin.com/58txTMzQ Commented Sep 12, 2018 at 2:01
  • If you have new code, edit your question or ask a new one. Comments are not meant for updates. Commented Sep 12, 2018 at 3:16

4 Answers 4

2

First Answer To make it a pointer you need to enclosed it within parentheses.

When reading such definitions start on the deepest name and spiral out starting up and to the right, honoring precedence.

void printMatriz(int (*matriz)[TAM][TAM])

Working from inside out, starting with name:

  • name matriz is (spiraling out within parentheses) a pointer to
  • [TAM][TAM] two-d array of
  • integers.

Using your original code:

void printMatriz(int *matriz[TAM][TAM])

Working from inside out:

  • name matriz is a
  • [TAM][TAM] two-d array of
  • pointers to
  • integers.

Hoping there is not too much sleep in my eyes.

Now that you have struggled Second answer now that you have dug a bit.

Use of typedef specifier can greatly simplify some definitions by encapsulating complexity within the typedef declaration.

typedef int matriz_t[TAM][TAM]; /* typedef simplifies referencing code */

void printTypedef(matriz_t *matriz)   /* (note: now a simple pointer) */
{
    int i, j;
    for(i = 0; i < TAM; i++) {
        for(j = 0; j < TAM; j++) {
            printf("%i\t", (*matriz)[j][i]);  /* still need () here */
        }
        printf("\n");
    }
}

int main()
{
    int i, j;
    matriz_t  matriztdef;               /* doesn't get simpler than this */
    for(i = 0; i < TAM; i++) {
        for(j = 0; j < TAM; j++) {
            printf("Matriz[%i][%i] = ", i, j);
            scanf("%i", &matriztdef[i][j]);
        }
    }
    printTypedef(&matriztdef);
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

i put void printMatriz(int (*matriz)[TAM][TAM]) and it still keeps displaying the warning, though it's working as well
Extended my answer now that you dug a little into the code.
2

You can afford to use far fewer asterisks, like this. Note that the printing code reverses the order of the subscripts compared to your code.

#include <stdio.h>

#define TAM 2
void printMatriz(int matriz[TAM][TAM]);

int main(void)
{
    int matriz[TAM][TAM];

    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
        {
            printf("Matriz[%i][%i] = ", i, j);
            if (scanf("%i", &matriz[i][j]) != 1)
            {
                fprintf(stderr, "failed to read an integer\n");
                return 1;
            }
        }
    }

    printMatriz(matriz);
    return 0;
}

void printMatriz(int matriz[TAM][TAM])
{
    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
            printf("%i\t", matriz[i][j]);  // Reversed order of i, j
        printf("\n");
    }
}

Sample run:

Matriz[0][0] = 19
Matriz[0][1] = 28
Matriz[1][0] = 30
Matriz[1][1] = 41
19  28  
30  41

Note that this uses C99 notation for the for loops, avoiding the need for the variables i and j outside the loops. If it's a problem, reinstate the variable definitions outside the loops.

If you really want to use pointers to matrices, you could use either of these two variants of your code:

#include <stdio.h>

#define TAM 2
void printMatriz(int (*matriz)[TAM]);

int main(void)
{
    int matriz[TAM][TAM];

    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
        {
            printf("Matriz[%i][%i] = ", i, j);
            if (scanf("%i", &matriz[i][j]) != 1)
            {
                fprintf(stderr, "failed to read an integer\n");
                return 1;
            }
        }
    }

    printMatriz(matriz);
    return 0;
}

void printMatriz(int (*matriz)[TAM])
{
    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
            printf("%i\t", matriz[i][j]);
        printf("\n");
    }
}

Or:

#include <stdio.h>

#define TAM 2
void printMatriz(int (*matriz)[TAM][TAM]);

int main(void)
{
    int matriz[TAM][TAM];

    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
        {
            printf("Matriz[%i][%i] = ", i, j);
            if (scanf("%i", &matriz[i][j]) != 1)
            {
                fprintf(stderr, "failed to read an integer\n");
                return 1;
            }
        }
    }

    printMatriz(&matriz);
    return 0;
}

void printMatriz(int (*matriz)[TAM][TAM])
{
    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
            printf("%i\t", (*matriz)[i][j]);
        printf("\n");
    }
}

Note the different notations needed in the last example — in the call (like in your original code) and in the use of the matrix.

Comments

0

You could do in this way:

#include <stdio.h>

#define TAM 2
void printMatriz(int **matriz);

int main(void)
{
    int **matriz=(int**)malloc(sizeof(int)*TAM);

    for (int i = 0; i < TAM; i++)
    {
        matriz[i]=(int*)malloc(sizeof(int)*TAM);
        for (int j = 0; j < TAM; j++)
        {
            printf("Matriz[%i][%i] = ", i, j);
            if (scanf("%i", &matriz[i][j]) != 1)
            {
                fprintf(stderr, "failed to read an integer\n");
                return 1;
            }
        }
    }

    printMatriz(matriz);
    return 0;
}

void printMatriz(int **matriz)
{
    for (int i = 0; i < TAM; i++)
    {
        for (int j = 0; j < TAM; j++)
            printf("%d ", matriz[i][j]);
        printf("\n");
     }
}

1 Comment

That's not a 2-dimensional matrix. That's an array of one-dimensional arrays. And it's a hugely inefficient way to allocate an array.
0

I want to pass the pointer of a 2d array

You can pass a pointer to the first element of the 2D array and access all the elements using that pointer like so:

#define TAM 2
void printMatrix(int * matrix); //function prototype

void printMatrix(int * matrix)
{
    int i, j;
    for(i = 0; i < TAM; i++) {
        for(j = 0; j < TAM; j++) {
            printf("%i\t", *(matrix + i*TAM + j));
        }
        printf("\n");
    }
}

In your main function you would do something like this:

int main()
{
    int i, j, matrix[TAM][TAM];
    for(i = 0; i < TAM; i++) {
        for(j = 0; j < TAM; j++) {
            printf("matrix[%i][%i] = ", i, j);
            scanf("%i", &matrix[i][j]);
        }
    }
    printMatrix(&matrix[0][0]); //could also do this other ways (e.g. matrix[0], *matrix) just wanted to make it explicit that you are passing a pointer to the first element of the 2D array 
    return 0;
}

I managed to make it work, but I still get the following warning:

||=== Build: Debug in matriz (compiler: GNU GCC Compiler) ===|
C:\Users\pauli\.dev\c\uvv\matriz\main.c||In function 'main':|
C:\Users\pauli\.dev\c\uvv\matriz\main.c|15|warning: passing argument 1 of 
'printMatriz' from incompatible pointer type [-Wincompatible-pointer-types]|
C:\Users\pauli\.dev\c\uvv\matriz\main.c|4|note: expected 'int * (*)[2]' but 
argument is of type 'int (*)[2][2]'|
C:\Users\pauli\.dev\c\uvv\matriz\main.c||In function 'printMatriz':|
C:\Users\pauli\.dev\c\uvv\matriz\main.c|23|warning: format '%i' expects argument 
of type 'int', but argument 2 has type 'int *' [-Wformat=]|
||=== Build finished: 0 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
||=== Run: Debug in matriz (compiler: GNU GCC Compiler) ===|

Your warnings are stemming from a misunderstanding of how you defined your function and then what you passed it. As others have stated, your function is defined as taking an argument of a 2D array of pointers to integers int * matrix[][], and since the name of the array is itself a pointer to the beginning of that array, the function wants a pointer to a pointer (remember the first element of int * matrix[][] will be a pointer to an int) but then you pass it &matrix which is int * (a pointer to an int) because the first element of the 2D array matrix is an int.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.