代码之家  ›  专栏  ›  技术社区  ›  Shweta

如何在C语言的函数中传递二维数组(矩阵)?

  •  45
  • Shweta  · 技术社区  · 15 年前

    我需要这样做,以便在矩阵上持久化操作。这是否意味着需要通过引用传递?

    这就够了吗?

    void operate_on_matrix(char matrix[][20]);

    6 回复  |  直到 7 年前
        1
  •  93
  •   Jonathan Leffler    7 年前

    C并没有真正的多维数组,但是有几种方法可以模拟它们。将此类数组传递给函数的方式取决于模拟多维数据的方式:

    1)使用数组。只有在编译时完全确定数组边界,或者编译器支持的情况下,才能使用此函数。 VLA's :

    #define ROWS 4
    #define COLS 5
    
    void func(int array[ROWS][COLS])
    {
      int i, j;
    
      for (i=0; i<ROWS; i++)
      {
        for (j=0; j<COLS; j++)
        {
          array[i][j] = i*j;
        }
      }
    }
    
    void func_vla(int rows, int cols, int array[rows][cols])
    {
      int i, j;
    
      for (i=0; i<rows; i++)
      {
        for (j=0; j<cols; j++)
        {
          array[i][j] = i*j;
        }
      }
    }
    
    int main()
    {
      int x[ROWS][COLS];
    
      func(x);
      func_vla(ROWS, COLS, x);
    }
    

    2)使用指向(动态分配)数组的指针数组(动态分配)。这通常在运行时才知道数组边界时使用。

    void func(int** array, int rows, int cols)
    {
      int i, j;
    
      for (i=0; i<rows; i++)
      {
        for (j=0; j<cols; j++)
        {
          array[i][j] = i*j;
        }
      }
    }
    
    int main()
    {
      int rows, cols, i;
      int **x;
    
      /* obtain values for rows & cols */
    
      /* allocate the array */
      x = malloc(rows * sizeof *x);
      for (i=0; i<rows; i++)
      {
        x[i] = malloc(cols * sizeof *x[i]);
      }
    
      /* use the array */
      func(x, rows, cols);
    
      /* deallocate the array */
      for (i=0; i<rows; i++)
      {
        free(x[i]);
      }
      free(x);
    }
    

    3)使用一维数组并固定索引。这可以用于静态分配(固定大小)和动态分配的数组:

    void func(int* array, int rows, int cols)
    {
      int i, j;
    
      for (i=0; i<rows; i++)
      {
        for (j=0; j<cols; j++)
        {
          array[i*cols+j]=i*j;
        }
      }
    }
    
    int main()
    {
      int rows, cols;
      int *x;
    
      /* obtain values for rows & cols */
    
      /* allocate the array */
      x = malloc(rows * cols * sizeof *x);
    
      /* use the array */
      func(x, rows, cols);
    
      /* deallocate the array */
      free(x);
    }
    

    4)使用动态分配的VLA。与选项2相比,这种方法的一个优点是有一个单独的内存分配;另一个优点是由于不需要指针数组,所以所需的内存更少。

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    extern void func_vla(int rows, int cols, int array[rows][cols]);
    extern void get_rows_cols(int *rows, int *cols);
    extern void dump_array(const char *tag, int rows, int cols, int array[rows][cols]);
    
    void func_vla(int rows, int cols, int array[rows][cols])
    {
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                array[i][j] = (i + 1) * (j + 1);
            }
        }
    }
    
    int main(void)
    {
        int rows, cols;
    
        get_rows_cols(&rows, &cols);
    
        int (*array)[cols] = malloc(rows * cols * sizeof(array[0][0]));
        /* error check omitted */
    
        func_vla(rows, cols, array);
        dump_array("After initialization", rows, cols, array);
    
        free(array);
        return 0;
    }
    
    void dump_array(const char *tag, int rows, int cols, int array[rows][cols])
    {
        printf("%s (%dx%d):\n", tag, rows, cols);
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
                printf("%4d", array[i][j]);
            putchar('\n');
        }
    }
    
    void get_rows_cols(int *rows, int *cols)
    {
        srand(time(0));           // Only acceptable because it is called once
        *rows = 5 + rand() % 10;
        *cols = 3 + rand() % 12;
    }
    

    (见 srand() — why call it only once? )

        2
  •  10
  •   casablanca    15 年前

    我不知道你所说的“数据不丢失”是什么意思。以下是将普通二维数组传递给函数的方法:

    void myfunc(int arr[M][N]) { // M is optional, but N is required
      ..
    }
    
    int main() {
      int somearr[M][N];
      ...
      myfunc(somearr);
      ...
    }
    
        3
  •  2
  •   Minhas Kamal    7 年前

    最简单的方法:传递可变长度的二维数组

    C++c++最干净的技术是:像一维数组一样传递2D数组,然后在函数内使用2D。

    void func(int row, int col, int* matrix){
        int i, j;
        for(i=0; i<row; i++){
            for(j=0; j<col; j++){
                printf("%d ", *(matrix + i*col + j)); // or better: printf("%d ", *matrix++);
            }
            printf("\n");
        }
    }
    
    int main(){
        int matrix[2][3] = { {1, 2, 3}, {7, 8, 9} };
        func(2, 3, matrix[0]);
    
        return 0;
    }
    
        4
  •  0
  •   shinxg    7 年前

    二维数组:

    int sum(int array[][COLS], int rows)
    {
    
    }
    

    三维阵列:

    int sum(int array[][B][C], int A)
    {
    
    }
    

    4D阵列:

    int sum(int array[][B][C][D], int A)
    {
    
    }
    

    ND阵列:

    int sum(int ar[][B][C][D][E][F].....[N], int A)
    {
    
    }
    
        5
  •  -2
  •   Rajneesh Gupta    15 年前

    如果编译器不支持VLA,您可以通过简单的方式将二维数组作为int*与row和col传递。 在接收函数中,从二维数组索引中重新生成一维数组索引。

    int 
    getid(int row, int x, int y) {
              return (row*x+y);
    }
    void 
    printMatrix(int*arr, int row, int col) {
         for(int x = 0; x < row ; x++) {
                 printf("\n");
                 for (int y = 0; y <col ; y++) {
                     printf("%d  ",arr[getid(row, x,y)]);
                 } 
         }                     
    }
    
    main()
    {
    
       int arr[2][2] = {11,12,21,22};
       int row = 2, col = 2;
    
       printMatrix((int*)arr, row, col);
    
     }
    
        6
  •  -3
  •   Casper Ghost    9 年前
         #include <iostream>
         using namespace std;
    
         void printarray(int *a, int c,int r)
         {
            for (int i = 0; i < r; i++)
            {
                for (int j = 0; j < c; j++)
                {
                    cout << "\t" << *(a + i*c + j) << "\t";  // a is a pointer refer to a 2D array
                }
            cout << endl << "\n\n";
            }
         }
    
         int main()
         {
             int array[4][4] = 
             {{1 ,2 ,3 ,4 },
              {12,13,14,5 },
              {11,16,15,6 },
              {10,9 ,8 ,7 }};
    
              printarray((int*)array,4,4);
              // here I use print function but u can use any other useful function like 
              //setArray((int *) array,4,4);
    
            return 0;
        }