Как скопировать матрицу в C?

Я пытаюсь написать функцию matricopy, которая должна копировать матрицу, но компилятор жалуется:

/* minmatrix.c - test rows and columns of a matrix
 * Copyright abandoned. This file is in the public domain. */

#include <stdio.h>
#define ROWCOUNT (3)
#define COLUMNCOUNT (4)

int imat[ ROWCOUNT ][ COLUMNCOUNT ]; 
char cmat[ ROWCOUNT ][ COLUMNCOUNT ];
double dmat[ ROWCOUNT ][ COLUMNCOUNT ];
int rmat[ ROWCOUNT ][ COLUMNCOUNT ]; 

void matriscopy (int * destmat, int * srcmat, int rowcount, int columncount) 
{
  int i, j;
  for (i=0; i<rowcount; i=i+1) /* rad-nr */
    for (j=0; j<columncount; j=j+1) /* kolumn-nr */
      destmat[i][j] = srcmat[i][j];
}

int main()
{
  int i; int j;
  int * ip; char * cp; double * dp;

  for( i = 0; i < ROWCOUNT; i = i + 1 )
    for( j = 0; j < COLUMNCOUNT; j = j + 1 )
    {
      imat[ i ][ j ] = 10000 + 100*i + j;
      cmat[ i ][ j ] = 10*i + j;
      dmat[ i ][ j ] = 1.0 + i/100.0 + j/10000.0;
      rmat[ i ][ j ] = 0;
    };

  printf( "n Examining imat:n" );
  for( ip = &imat[ 0 ][ 0 ];
       ip <= &imat[ ROWCOUNT - 1 ][ COLUMNCOUNT - 1 ];
       ip = ip + 1 )
    printf( "memory at: %lx contains value: %dn", (unsigned long) ip, *ip );

  printf( "n Examining cmat:n" );
  for( cp = &cmat[ 0 ][ 0 ];
       cp <= &cmat[ ROWCOUNT - 1 ][ COLUMNCOUNT - 1 ];
       cp = cp + 1 )
    printf( "memory at: %lx contains value: %dn", (unsigned long) cp, *cp );

  printf( "n Examining dmat:n" );
  for( dp = &dmat[ 0 ][ 0 ];
       dp <= &dmat[ ROWCOUNT - 1 ][ COLUMNCOUNT - 1 ];
       dp = dp + 1 )
    printf( "memory at: %lx contains value: %fn", (unsigned long) dp, *dp );

/* Add a statement here to call your matriscopy function. */

  printf( "n Examining rmat:n" );
  for( ip = &rmat[ 0 ][ 0 ];
       ip <= &rmat[ ROWCOUNT - 1 ][ COLUMNCOUNT - 1 ];
       ip = ip + 1 )
    printf( "memory at: %lx contains value: %dn", (unsigned long) ip, *ip );

  return( 0 );
}

Я получаю эту ошибку:

$ cc minmatrix.c
minmatrix.c: In function ‘matriscopy’:
minmatrix.c:18:17: error: subscripted value is neither array nor pointer nor vector
minmatrix.c:18:32: error: subscripted value is neither array nor pointer nor vector

можете ли вы помочь мне понять?

6 ответов


вы можете просто использовать memcpy

void matriscopy (void * destmat, void * srcmat) 
{
  memcpy(destmat,srcmat, ROWCOUNT*COLUMNCOUNT*sizeof(int));
}

на destmat и srcmat должен иметь тот же размер.

эта функция позволяет копировать только всю матрицу.

эта функция не может скопировать подматрицу из материнской матрицы.

пример: если у меня есть матрица с 7 столбцами и 7 строками. Я не могу скопировать с помощью вышеуказанной функции подматрицу (4 строки и 4 столбца) из материнской матрицы. Чтобы сделать это, мы должны сделать копию клетка за клеткой!--4-->


код matrixcopy сигнатура функции должна выглядеть так:

void matrixcopy (int destmat[][COLUMNCOUNT], int srcmat[][COLUMNCOUNT], int rowcount, int columncount) 

конечно, тогда columncount является избыточным.

кроме того, вы можете рассматривать матрицу как 1D массив rowcount * columncount целых чисел. В этом случае вы можете сделать копию в одном цикле или использовать функцию memcpy из стандартной библиотеки.


правильное объявление для вашей функции:

void matriscopy (int destmat[][COLUMNCOUNT], int srcmat[][COLUMNCOUNT], int rowcount) 

таким образом, ваша функция становится

void matriscopy (int destmat[][COLUMNCOUNT], int srcmat[][COLUMNCOUNT], int rowcount) 
{
  int i, j;
  for (i=0; i<rowcount; i=i+1) /* rad-nr */
    for (j=0; j<COLUMNCOUNT; j=j+1) /* kolumn-nr */
      destmat[i][j] = srcmat[i][j];
}

в массиве multidimensinal все axcept первого измерения должны быть закреплены в аргументе функции.


попробуйте эту версию matriscopy.

void matriscopy (int * destmat, int * srcmat, int rowcount, int columncount)
{
  int i, j;
  int (*dst)[columncount];
  int (*src)[columncount];
  dst = (int (*)[columncount])destmat;
  src = (int (*)[columncount])srcmat;
  for (i=0; i<rowcount; i=i+1) /* rad-nr */
    for (j=0; j<columncount; j=j+1) /* kolumn-nr */
      dst[i][j] = src[i][j];
}

C позволяет массивам переменной длины (VLA) с стандарта c99.


на matriscopy переменная destmat - целочисленный указатель. Это означает, что тип destmat[i] - целое число. Поскольку вы не можете индексировать в целое число, вы не можете иметь destmat[i][j]. Вы, вероятно, хотите destmat тип int** не int*.


destmat и srcmat должны быть двойными указателями. Как int **destmat,int **srcmat поскольку вы фактически пытаетесь получить доступ к массиву целочисленных указателей, которые указывают на некоторые целочисленные объекты.Как[i][j], вы знаете объект в j-м столбце i-го ряда. Поэтому, когда вы определяете int * * p; это похоже на P-массив указателей, каждый из которых указывает на целочисленный объект.Тогда вы можете получить к нему доступ, как p[i] [j]. Отметьте это как ответ, если это решило вашу проблему.