简体   繁体   中英

Passing 2d array to a function in C with pointers

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");
    }
}

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.

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;
}

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.

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");
     }
}

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM