【问题标题】:Passing 2d array to a function in C with pointers使用指针将二维数组传递给 C 中的函数
【发布时间】:2018-09-12 00:35:08
【问题描述】:

我是 C 新手,我正在学习指针。所以,我想传递一个二维数组的指针。我设法让它工作,但我仍然收到以下警告:

||=== 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) ===|

这是我的代码:

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

【问题讨论】:

  • 您为什么声称该函数接收int * 值的矩阵?从函数原型和定义中删除*
  • 参见stackoverflow.com/questions/14808908/… 了解如何定义指向二维数组的指针。在您的 printMatriz 函数中,您还需要取消引用指向数组的指针(在 printf 语句中的 matriz 前面添加一个 *)。
  • 函数声明中的 int *matriz[][] 表示指向 int 的 指针 的二维数组。在“main”中,您将其声明为仅 int 的 2D 数组:int matriz[][]。这些是不兼容的类型。删除“*”。
  • 我忘记将其声明为指针。现在我做到了,它一直显示警告,这是现在的代码pastebin.com/58txTMzQ
  • 如果您有新代码,edit您的问题或提出新问题。评论不用于更新。

标签: c arrays pointers


【解决方案1】:

第一个答案 要使其成为指针,您需要将其括在括号内。

当阅读此类定义时,从最深的名称开始,然后从右侧开始,尊重优先级。

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

从内到外,从名字开始:

  • name matriz 是(在括号内螺旋)一个指向
  • [TAM][TAM] 的二维数组
  • 整数。

使用您的原始代码:

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

由内而外的工作:

  • 名字matriz是一个
  • [TAM][TAM] 的二维数组
  • 指向的指针
  • 整数。

希望我的眼睛里没有太多的睡眠。

现在你已经挣扎了 第二个答案现在你已经挖了一点。

使用typedef 说明符可以通过在 typedef 声明中封装复杂性来大大简化一些定义。

typedef int matriz_t[TAM][TAM]; /* typedef 简化了引用代码 */

void printTypedef(matriz_t *matriz) /*(注意:现在是一个简单的指针)*/
{
    整数 i, j;
    for(i = 0; i 
    

【讨论】:

  • 我放了 void printMatriz(int (*matriz)[TAM][TAM]) 并且它仍然继续显示警告,尽管它也能正常工作
  • 扩展了我的答案,因为您对代码进行了一些研究。
【解决方案2】:

您可以使用更少的星号,像这样。请注意,与您的代码相比,打印代码颠倒了下标的顺序。

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

示例运行:

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

请注意,这对 for 循环使用 C99 表示法,避免了循环外部变量 ij 的需要。如果有问题,请在循环外恢复变量定义。

如果您真的想使用指向矩阵的指针,您可以使用以下两种代码变体中的任何一种:

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

或者:

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

注意上一个示例中需要的不同符号——在调用中(就像在您的原始代码中一样)和在矩阵的使用中。

【讨论】:

    【解决方案3】:

    你可以这样做:

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

    【讨论】:

    • 那不是二维矩阵。那是一维数组的数组。而且这是一种非常低效的数组分配方式。
    【解决方案4】:

    我想传递一个二维数组的指针

    您可以将指针传递给二维数组的第一个元素,并使用该指针访问所有元素,如下所示:

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

    在你的主函数中,你会做这样的事情:

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

    我设法让它工作,但我仍然收到以下警告:

    ||=== 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) ===|
    

    您的警告源于对您如何定义函数以及传递它的内容的误解。正如其他人所说,您的函数被定义为采用指向整数int * matrix[][] 的二维指针数组的参数,并且由于数组的名称本身就是指向该数组开头的指针,因此该函数需要 a指向指针的指针(请记住int * matrix[][] 的第一个元素将是指向int 的指针) 但随后您将其传递给&amp;matrix,即int *(指向int 的指针),因为二维数组matrix 的第一个元素是int

    【讨论】:

      猜你喜欢
      • 2016-04-27
      • 1970-01-01
      • 2014-05-09
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 2011-07-16
      相关资源
      最近更新 更多