【问题标题】:C-2d array print function not working when I call it in main function当我在主函数中调用它时,C-2d 数组打印函数不起作用
【发布时间】:2021-12-15 18:16:19
【问题描述】:

我写了两个函数,readMatrix 分配一个双指针并从键盘获取输入,第二个函数是打印函数。

当我在主函数中调用打印函数时,它并没有完全起作用。

这是代码:

void print(int** mat, int lin, int col) {
    int i,j;
    printf("Matrix is:\n");
    for(i=0; i<lin; i++) {
        for(j=0; j<col; j++) {
            printf("%d ", *(*(mat+i)+j));
        }
        printf("\n");
    }
}

int** readMatrix(int** mat, int lin, int col) {
    int x;
    int i,j;
    mat==(int**)malloc(lin*sizeof(int*));
    for(x=0; x<lin; x++) {
        mat[x]=(int*)malloc(col*sizeof(int));
    }
    
    for(i=0; i<lin; i++) {
        printf("Line %d: ", i);
        for(j=0; j<col; j++) {
            scanf("%d",  &mat[i][j]);
        }
    }
}


int main()
{
    int lin, col;
    int i,j;
    printf("Enter number of lines: ");
    scanf("%d", &lin);
    printf("Enter number of cols: ");
    scanf("%d", &col);
    int** mat = readMatrix(mat,lin,col);
    print(mat,lin,col);
    return 0;
}

输入后,我得到消息“矩阵是”,但矩阵没有出现,为什么?

如果我在 readMatrix 函数中调用 print 函数,它可以工作,但如果我在 main 中调用它为什么不工作?

谢谢。

【问题讨论】:

  • 关于:mat==(int**)malloc(lin*sizeof(int*)); 和类似的语句:1)返回的类型(在 C 中)是void*,可以分配给任何指针。强制转换只会使代码混乱并且容易出错。 2) 对于健壮的代码,始终检查 (!=NULL) 返回值以确保操作成功

标签: c pointers multidimensional-array malloc dynamic-memory-allocation


【解决方案1】:

函数readMatrix中没有使用参数mat,因为它的值id被覆盖了

int** readMatrix(int** mat, int lin, int col) {
    int x;
    int i,j;
    mat==(int**)malloc(lin*sizeof(int*));
    //...

此外,尽管它的返回类型不是 void,但该函数什么也不返回。

所以这条记录

int** mat = readMatrix(mat,lin,col);

调用未定义的行为。

你需要声明函数至少是谎言

int** readMatrix( int lin, int col);

并在函数的末尾写

return mat;

例如

int** readMatrix(int lin, int col) {
    int **mat==(int**)malloc(lin*sizeof(int*));
    //...

    return mat;
}

函数会像这样调用

int** mat = readMatrix(lin,col);

同样在 main 中,当不再需要数组时,您应该释放所有分配的内存。

例如

for ( i = 0; i < lin; i++ )
{
    free( mat[i] );
}

free( mat );

【讨论】:

  • 谢谢,我忘了返回矩阵。所以我应该从列表参数中删除垫子,我应该在函数内部声明 int** mat = ....,对吗?我想这样做,但我读到如果我返回一个局部变量,比如 **mat,当我调用函数时,它不应该被销毁吗?像普通变量一样?
  • 我按照你说的做了,效果很好,谢谢!但我仍然想知道返回一个局部变量。如果我返回一个局部变量(我知道这是不允许的)并返回一个指针有什么区别?
  • @ValiRO 您还需要释放 main 中所有分配的内存。
  • 好的,谢谢:)
  • @ValiRO 完全没有。我赞成你的问题。:)
【解决方案2】:

readMatrixmat 作为参数,但这没有用,因为它只接收它的值,而它还没有值。 (为了能够更改调用例程中的变量,例程必须接收指向它的指针,而不是它的值。)

readMatrix 被声明为返回 int **,但没有 return 语句。

mat==(int**)malloc(lin*sizeof(int*)); 使用==,它比较值。它不执行分配。

readMatrix 的声明中删除mat 参数。从对readMatrix 的调用中删除mat 参数。将== 更正为=。添加一个return 语句,该语句从readMatrix 中执行的分配中返回mat 的值。

【讨论】:

  • 谢谢,我忘了返回矩阵。所以我应该从列表参数中删除垫子,我应该在函数内部声明 int** mat = ....,对吗?我想这样做,但我读到如果我返回一个局部变量,比如 **mat,当我调用函数时,它不应该被销毁吗?像普通变量一样?
  • 我按照你说的做了,效果很好,谢谢!但我仍然想知道返回一个局部变量。如果我返回一个局部变量(我知道这是不允许的)并返回一个指针有什么区别?
  • @ValiRO:您可以返回局部变量的值。您不应返回本地自动变量的地址。一旦你知道了一个变量的值,你就知道了这个值,所以这个值可以安全地返回。但是,当您知道变量的地址时,它在其生命周期内只有该地址。当一个函数返回时,它的局部自动变量的生命周期结束,它们以前的地址变得无效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-01
  • 2015-02-08
相关资源
最近更新 更多