简体   繁体   English

使用指针将2d数组传递给C中的函数

[英]Passing 2d array to a function in C with pointers

I'm new to C and I'm learning pointers. 我是C语言的新手,正在学习指针。 So, I want to pass the pointer of a 2d array. 因此,我想传递2D数组的指针。 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");
    }
}

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 名称matriz是(在圆括号内鼓出)指向的指针
  • [TAM][TAM] two-d array of [TAM] [TAM]的二维数组
  • integers. 整数。

Using your original code: 使用原始代码:

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

Working from inside out: 由内而外的工作:

  • name matriz is a 名称matriz是一个
  • [TAM][TAM] two-d array of [TAM] [TAM]的二维数组
  • 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说明符可以通过将复杂性封装在typedef声明中来极大地简化某些定义。

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. 请注意,这对于for循环使用C99表示法,从而避免了在循环外使用变量ij 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 我想传递2D数组的指针

You can pass a pointer to the first element of the 2D array and access all the elements using that pointer like so: 您可以将指针传递到2D数组的第一个元素,并使用该指针访问所有元素,如下所示:

#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 . 正如其他人所述,您的函数被定义为采用指向整数int * matrix[][]的2D指针数组的参数,并且由于数组的名称本身就是指向该数组开头的指针,因此该函数需要一个指针的指针(记住int * matrix[][]的第一个元素将是一个指向int的指针) ,然后将它传递给&matrix ,它是int * (一个指向int的指针),因为2D的第一个元素数组matrix是一个int

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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