【问题标题】:How to change the content of a 2d array in C?如何在 C 中更改二维数组的内容?
【发布时间】:2019-04-11 00:30:52
【问题描述】:

我正在解决一个必须转置矩阵的问题。我正在传递原始矩阵的地址,但是一旦执行该函数,它就不会改变!

我曾尝试在转置函数中添加一个 * infront 的矩阵,以为它会指向整个二维数组,但它不起作用。

#include<stdio.h>
#include <stdlib.h>

void transpose(int *r,int *c, int **matrix);
void printMatrix(int r,int c, int **matrix){
  for(int i=0;i<r;i++){
      for(int j=0;j<c;j++)
        printf("%2d ",matrix[i][j]);
      printf("\n");  
  }
}

int main() {

  int **matrix;
  int r =3;
  int c =2;
  matrix = (int**) malloc(r*sizeof(int*)); 
  for(int i=0;i<r;i++)
    matrix[i] = (int*) malloc(c*sizeof(int));

   for(int i=0;i<r;i++){
      for(int j=0;j<c;j++)
        matrix[i][j] = (3*i+2*j)%8+1; 
  }
  printf("Before transpose:\n");
  printMatrix(r,c,matrix);

   transpose(&r, &c ,matrix);

  printMatrix(r,c,matrix);



return 0;
}

void transpose(int *r,int *c, int **matrix){
  int newR = *c;
  int newC = *r;
  int **newMatrix;

  newMatrix = (int**) malloc(newR*(sizeof(int*)));
  for(int i=0; i<newR;i++)
    newMatrix[i] = (int*) malloc(newC*(sizeof(int)));
  for(int i=0; i<newR; i++)
    for(int j=0;j<newC;j++)
      newMatrix[i][j] = matrix[j][i];

  *c = newC;
  *r = newR;



  matrix = (int**) malloc((*r)*sizeof(int*)); 
  for(int i=0;i<*r;i++)
    matrix[i] = (int*) malloc((*c)*sizeof(int));
  for(int i=0; i<newR; i++){
    for(int j=0;j<newC;j++){
      matrix[i][j] = newMatrix[i][j];
    }
 printf("\n");  
  }
}

我有这个矩阵

1 3
4 6
7 1

想要得到

1 4 7 
3 6 1

不管怎样

1 3 0
1 4 0

【问题讨论】:

  • 调用者应该如何看到新矩阵?您在本地创建它,填写它,然后返回。到时候它就死了。调用者永远不会看到它。您需要返回新指针(或传递 int *** 并通过它进行设置)。
  • transpose 函数永远不会使调用者可以使用新矩阵
  • @M.M 假设它不打算改变 int **matrix,这看起来确实可能是意图。
  • @Kbiir 不直接相关,但通常对于动态二维数组,您可能需要考虑使用一维数组和类似arr[column * width + row] 的东西。这使它保持在单个内存块中,更少的内存,没有额外的间接,单个malloc,单个free(可能是最容易忘记然后泄漏的位)。
  • 注意:这不是二维数组——它是一维数组的指针指向一维数组。 2D 数组(例如 matrix = malloc(r*c*sizeof(int));)可能会更快,并且占用更少的内存。

标签: c arrays pointers multidimensional-array memory-address


【解决方案1】:

看起来您实际上忘记做的只是使用转置矩阵。我所做的只是更改函数签名并返回您已经分配和操作的矩阵,然后我得到了您正在寻找的输出。

#include <stdio.h>
#include <stdlib.h>

int** transpose(int *r,int *c, int **matrix);

void printMatrix(int r, int c, int **matrix) {
    for (size_t i = 0; i < r; ++i){
        for (size_t j = 0; j < c; ++j) {
            printf("%2d ",matrix[i][j]);
        }

        printf("\n");  
    }
}

int main()
{
    int r = 3;
    int c = 2;

    int **matrix = calloc(sizeof(int*), r);

    for (size_t i = 0; i < r; ++i) {
        matrix[i] = calloc(sizeof(int), c);
    }

    for (size_t i = 0; i < r; ++i) {
        for (size_t j = 0; j < c; ++j) {
            matrix[i][j] = (3 * i + 2 * j) % 8 + 1; 
        }
    }

    printf("Before transpose:\n");
    printMatrix(r, c, matrix);

    int** newMatrix = transpose(&r, &c ,matrix);

    printMatrix(r, c, newMatrix);

    return EXIT_SUCCESS;
}

int** transpose(int *r, int *c, int **matrix) {
    int newR = *c;
    int newC = *r;

    int **newMatrix = calloc((sizeof(int*)), newR);

    for (size_t i = 0; i < newR; ++i) {
        newMatrix[i] = (int*) malloc(newC*(sizeof(int)));
    }

    for (size_t i = 0; i < newR; ++i) {
        for (size_t j = 0; j < newC; ++j) {
            newMatrix[i][j] = matrix[j][i];
        }
    }

    *c = newC;
    *r = newR;

    matrix = calloc(sizeof(int*), *r); 

    for (size_t i = 0; i < *r; ++i) {
        matrix[i] = calloc(sizeof(int), *c);
    }

    for (size_t i = 0; i < newR; ++i) {
        for (size_t j = 0; j < newC; ++j) {
            matrix[i][j] = newMatrix[i][j];
        }

        printf("\n");  
    }

    return newMatrix;
}

输出:

1 4 7
3 6 1

我改变了一些东西,特别是因为我更喜欢使用calloc 而不是malloc,因为它会将新分配的内存归零,并且有一个用于请求内存大小的专用参数,我认为这是语义上的是一个更好的主意。

作为旁注,您不必在 C 中转换 malloc 的结果。我认为,我倾向于比其他人更强烈地感觉到这一点,因为代码噪音,尤其是当您工作时C是你可以对自己做的最糟糕的事情之一。这是一个很好的例子,因为我所做的只是重新格式化您的代码,而答案就在那里。也不要吝啬空格;它确实有所作为。

无论如何,我希望这会有所帮助,即使您基本上已经完成了所有工作。

【讨论】:

    【解决方案2】:
    #include<stdio.h>
    #include <stdlib.h>
    
    void transpose(int *r,int *c, int ***matrix);
    void printMatrix(int r,int c, int **matrix){
        int i=0,j=0;
      for(i=0;i<r;i++){
          for(j=0;j<c;j++)
            printf("%2d ",matrix[i][j]);
          printf("\n");  
      }
    }
    
    int main() {
    
      int **matrix;
      int r =3;
      int c =2;
      int i=0,j=0;
    
      matrix = (int**) malloc(r*sizeof(int*)); 
      for(i=0;i<r;i++)
        matrix[i] = (int*) malloc(c*sizeof(int));
    
       for(i=0;i<r;i++){
          for(j=0;j<c;j++)
            matrix[i][j] = (3*i+2*j)%8+1; 
      }
      printf("Before transpose:\n");
      printMatrix(r,c,matrix);
    
       transpose(&r, &c, &matrix);
    
      printMatrix(r,c,matrix);
    
    
    
    return 0;
    }
    
    void transpose(int *r,int *c, int ***matrix){
      int newR = *c;
      int newC = *r;
      int **newMatrix;
      int i=0,j=0;
    
      newMatrix = (int**) malloc(newR*(sizeof(int*)));
      for(i=0; i<newR;i++)
        newMatrix[i] = (int*) malloc(newC*(sizeof(int)));
      for(i=0; i<newR; i++)
        for(j=0;j<newC;j++) {
          newMatrix[i][j] = (*matrix)[j][i];
        }
    
      *c = newC;
      *r = newR;
    
      // free matrix..
    
      *matrix = newMatrix;
    
    
      /*matrix = (int**) malloc((*r)*sizeof(int*)); 
      for(i=0;i<*r;i++)
        matrix[i] = (int*) malloc((*c)*sizeof(int));
      for(i=0; i<newR; i++){
        for(j=0;j<newC;j++){
          matrix[i][j] = newMatrix[i][j];
        }
     printf("\n");  
      }*/
    
    }
    

    【讨论】:

    • 您应该简要解释为什么原始代码不起作用以及您是如何使其起作用的。你不应该只是发布代码。
    猜你喜欢
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2018-08-29
    • 2011-01-28
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多