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");
    }
}
  • 1
    Why are you claiming that the function receives a matrix of `int *` values? Drop the `*` from the function prototype and definition. – Jonathan Leffler Sep 12 '18 at 01:02
  • See https://stackoverflow.com/questions/14808908/c-pointer-to-two-dimensional-array 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) . – dernst Sep 12 '18 at 01: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 '*'. – Serge Sep 12 '18 at 01:36
  • i forgot to declare it as a pointer. Now that I did it, it keeps displaying the warning, here is the code now https://pastebin.com/58txTMzQ – Paulo Henrique Rodrigues Grund Sep 12 '18 at 02:01
  • If you have new code, [edit] your question or ask a new one. Comments are not meant for updates. – n. m. could be an AI Sep 12 '18 at 03:16

4 Answers4

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;
}
Gilbert
  • 3,740
  • 17
  • 19
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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
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");
     }
}
  • 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. – Andrew Henle Sep 12 '18 at 09:13
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.

bigwillydos
  • 1,321
  • 1
  • 10
  • 15