从C中的函数返回二维数组

时间:2017-04-11 17:44:43

标签: c function matrix

首先,我需要获取matrix_a的值,然后将其转置为matrix_t。在此之后,我需要在两个矩阵上打印值。    我以前和Java一起工作,我刚开始使用C编程,所以如果有人花时间向我解释这段代码有什么问题,我将非常感激。

#include <stdio.h>

int[][] insert_value_matrix(int[][] matrix);
int[][] transpose_matrix(int[][] matrix);
void show_matrix(int[][] matrix);

int main(){

  int matrix_a[3][3] = insert_value_matrix(matrix_a);
  int matrix_t[][] = transpose_matrix(matrix_a);
  show_matrix(matrix_a);
  show_matrix(matrix_t);

  return 0;
}

int[][]  insert_value_matrix(int[][] matrix)
{
  for (int i=0; i<3; i++){
    for(int j=0; j<3; j++){ scanf("%d", &matrix[i][j]); }
  }
  return matrix;
}

int[][] transpose_matrix(int[][] matrix)
{
  int[][] matrix_transposed;

  for (int i=0; i<3; i++){
    for(int j=0; j<3; j++){ matrix_transposed[j][i] = matrix[i][j]; }
  }
  return matrix_transposed;
}

void show_matrix(int[][] matrix)
{
  for (int i=0; i<3; i++){
    for (int j=0; j<3; j++){printf("%d", matrix[i][j]);}
    printf("\n");
  }
}

2 个答案:

答案 0 :(得分:0)

C并不具备适合矩阵的任何类型,因此您必须自己从结构中创建它。类似的东西:

typedef struct {
    int m, n;
    int data[];
} matrix;

matrix *new_matrix(m, n) {
    matrix *obj = malloc(sizeof(matrix) + m * sizeof(int));
    obj->m = m;
    obj->n = n;
    for (int i = 0; i < m; i += 1) {
        obj->data[i] = malloc(n * sizeof(int));
    }
    return obj;
}
. . .

答案 1 :(得分:0)

关于C的几件事:

  • 数组表达式不能成为作业的目标,因此根本不允许
    int matrix_a[3][3] = insert_value_matrix(matrix_a);
    int matrix_t[][] = transpose_matrix(matrix_a);
    之类的调用;
  • 函数不能返回数组类型(并且不能有函数类型的数组);
  • 在大多数情况下,数组类型的表达式将转换为指针类型的表达式。当您使用数组表达式作为参数调用函数时,函数实际接收的是指针值:
    int main( void )
    {
      int a[3];
      int b[3][3];
    
      foo( a );
      bar( b );
      ...
    }
    
    void foo( int *arr )
    {
      ...
    }
    
    void bar( int (*arr)[3] )
    {
       ...
    }
    
  • 必须在其声明中指定数组的;对于作为函数参数的数组,可以省略最内层维度:
    void foo( int arr[] ) { ... } // same as int *arr
    void bar( int arr[][3] ) { ... } // same as int (*arr)[3]
    
    在函数参数声明的上下文中,T a[N]T a[]被解释为T *a;所有三个都将a声明为指向T的指针;

函数可以将指针返回到数组,但语法有点傻:

int (*transpose_matrix( int matrix[][3] ))[3]
{
  int (*xpos)[3] = malloc( 3 * sizeof *xpos ); // dynamically allocate a 3x3 array of int

  // do the transpose thing

  return xpos;
}

int (*matrix_t)[3] = transpose_matrix( matrix_a ); 

matrix_t需要在某个时候明确free - C不进行垃圾回收。

transpose_matrix的函数原型读为

      transpose_matrix                           -- transpose_matrix
      transpose_matrix(                 )        -- is a function taking
      transpose_matrix(     matrix      )        --   parameter matrix 
      transpose_matrix(     matrix[]    )        --   is a pointer to a
      transpose_matrix(     matrix[][3] )        --   3-element array of
      transpose_matrix( int matrix[][3] )        --   type int
     *transpose_matrix( int matrix[][3] )        -- returning a pointer to a
    (*transpose_matrix( int matrix[][3] ))[3]    -- 3-element array of
int (*transpose_matrix( int matrix[][3] ))[3]    -- int

坦率地说,您最好分配源数组和目标数组,并将两者作为函数的参数传递:

void transpose_matrix( int (*src)[3], int (*dst)[3] )
{
  // do the thing
}

int main( void )
{
  int matrix_a[3][3];
  int matrix_t[3][3];

  transpose_matrix( matrix_a, matrix_t );
  ...
}

但是,这只能用于Nx3数组,因为指向int的3元素数组的指针与指向4元素的指针的不兼容类型不同int的数组,它是一个不同的,不兼容的类型,指向int的2元素数组的指针等。由于以这种方式声明的2D数组是连续的,您可以传递第一个元素的地址的数组,然后在函数中将其视为一维数组:

void transpose_matrix( int *src, int *dst, size_t rows, size_t cols )
{
  for ( size_t i = 0; i < rows; i++ )
    for ( size_t j = 0; j < cols; j++ )
      dst[j * cols + i] = src[i * rows + j];
}

int main( void )
{
  int matrix_a[3][4];
  int matrix_t[4][3];

  transpose_matrix( &matrix_a[0][0], &matrix_t[0][0], 3, 4 );
  ...
}

如果您正在使用C99或更高版本的实现,则可以使用可变长度数组:

/**
 * Since rows and cols are used in the declarations of src and dst, they
 * must be declared first
 */
void transpose_matrix( size_t rows, size_t cols, int src[rows][cols], int dst[cols][rows] )
{
  for ( size_t i = 0; i < rows; i++ )
    for ( size_t j = 0; j < cols; j++ )
      dst[j][i] = src[i][j];
}

int main( void )
{
  int matrix_a[3][4];
  int matrix_t[4][3];

  transpose_matrix( 3, 4, matrix_a, matrix_t );
  ...
}

需要注意的是,这可能不适用于大型数组,具体取决于实现如何处理VLA。