Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 泛型矩阵:如何在函数参数中传递类型_C_Generics_Matrix - Fatal编程技术网

C 泛型矩阵:如何在函数参数中传递类型

C 泛型矩阵:如何在函数参数中传递类型,c,generics,matrix,C,Generics,Matrix,我创建了一个通用矩阵结构,如下所示: typedef struct mat_t { /** * \brief matrix structure */ unsigned int c, l; void **matrice; }* mat; 我的问题是学习如何为矩阵分配内存,因为它可以包含复数、浮点数或其他。。。 因此,我想知道如何将类型传递给函数参数以分配内存 mat allocate_mat(unsigned int l, unsigned int c, **<ty

我创建了一个通用矩阵结构,如下所示:

typedef struct mat_t {
  /**
   * \brief matrix structure
   */
  unsigned int c, l;
  void **matrice;
}* mat;
我的问题是学习如何为矩阵分配内存,因为它可以包含复数、浮点数或其他。。。 因此,我想知道如何将类型传递给函数参数以分配内存

mat allocate_mat(unsigned int l, unsigned int c, **<type>** )
mat分配\u mat(无符号整数l,无符号整数c,*****)

也许,我应该为此函数使用定义宏吗?

您可以传递矩阵元素的大小:

mat allocate_mat(unsigned int l, unsigned int c, unsigned int size_of_matrix_element )
也许,我应该为这个函数使用define宏吗

是的,您可以定义一个宏以在最后一个参数中采用类型,并调用在最后一个参数中采用大小的实函数

#define allocate_mat(MAT_L, MAT_C, MAT_TYPE) allocate_mat_sz(MAT_L, MAT_C, sizeof(MAT_TYPE))
mat allocate_mat_sz (unsigned l, unsigned c, size_t size);

问题1:奇怪的变量名。
l
c
应该是什么意思?“台词”,“计数”?在C语言中没有任何东西可以阻止你使用全字作为变量名

问题2:您很可能使用了一个错误的准2D数组,带有指针到指针的表示法,这会导致堆碎片崩溃。它不仅速度慢并导致堆碎片,而且不能与基本的C函数如memset()、memcpy()一起使用。而是在相邻内存中分配一个真正的2D数组

问题3:为什么在结构typedef的末尾有
*mat
?这没有任何意义

以下是使用通用C编程的动态矩阵的基本实现:

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

typedef struct mat_t
{
  void** data;
  size_t row_n;
  size_t col_n;
  size_t obj_size;
} matrix_t;


bool matrix_init (matrix_t* mat, 
                  size_t    row_n, 
                  size_t    col_n,
                  size_t    obj_size)
{
  mat->row_n = row_n;
  mat->col_n = col_n;
  mat->obj_size = obj_size;

  mat->data = calloc(row_n * col_n, obj_size);

  return mat->data != NULL;
}


void matrix_free (matrix_t* mat)
{
  free(mat);
}


void matrix_set (matrix_t* mat,
                 size_t    x,
                 size_t    y,
                 void*     val)
{
  size_t data_offset = y * mat->row_n * mat->obj_size + 
                       x * mat->obj_size;

  memcpy (mat->data + data_offset,
          val,
          mat->obj_size);
}


void* matrix_get (const matrix_t* mat,
                  size_t x,
                  size_t y)
{
  size_t data_offset = y * mat->row_n * mat->obj_size + 
                       x * mat->obj_size;

  return mat->data + data_offset;
}


int main()
{
  matrix_t mat;
  const int ROWS=3;
  const int COLS=2;

  // allocate memory
  matrix_init(&mat, ROWS, COLS, sizeof(int));


  // fill memory with data 1,2,3...
  int count =0;
  for(int row=0; row<ROWS; row++)
  {
    for(int col=0; col<COLS; col++)
    {
      count++;
      matrix_set (&mat, row, col, &count);
    }
  }

  // print the matrix
  for(int row=0; row<ROWS; row++)
  {
    printf("[ ");
    for(int col=0; col<COLS; col++)
    {
      printf("%d ", *(int*)matrix_get(&mat, row, col));
    }
    printf("]\n");
  }

  matrix_free(&mat);
  return 0;
}
#包括
#包括
#包括
#包括
类型定义结构材料
{
作废**数据;
大小排;
大小列;
尺寸和目标尺寸;
}矩阵t;
布尔矩阵(矩阵),
尺寸排,
大小列,
尺寸(目标尺寸)
{
mat->row\u n=row\u n;
mat->col\u n=col\u n;
mat->obj_尺寸=obj_尺寸;
mat->data=calloc(行*列,对象大小);
返回mat->data!=NULL;
}
无空隙基质(基质)
{
免费(mat);
}
空矩阵集(矩阵),
尺寸,
尺寸,
void*val)
{
尺寸数据偏移量=y*mat->row\n*mat->obj\U尺寸+
x*mat->obj_尺寸;
memcpy(材料->数据+数据偏移,
瓦尔,
mat->obj_尺寸);
}
void*matrix_get(const matrix_t*mat,
尺寸,
尺寸(y)
{
尺寸数据偏移量=y*mat->row\n*mat->obj\U尺寸+
x*mat->obj_尺寸;
返回物料->数据+数据偏移量;
}
int main()
{
基质材料;
const int ROWS=3;
常数int COLS=2;
//分配内存
矩阵_init(&mat,ROWS,COLS,sizeof(int));
//用数据1,2,3填充内存。。。
整数计数=0;

对于(int row=0;row为什么不只传递类型的大小?比如,
mat allocate\u mat(unsigned int l,unsigned int c,unsigned int size)
然后这样调用:
allocate\u mat(10,5,sizeof(float))
是的,但是我需要两个malloc作为我的矩阵。因此,我需要两个sizeof(),一个用于元素指针,一个用于元素。如果我只传递矩阵元素的大小,我如何处理它?@user2412542所有指针的大小都相同;例如,
sizeof(void*)
将告诉您它是什么。@MattPhillips好的,我想用sizeof(void*)制作一个malloc这可能是个错误,但看起来不错!THKSY您可以使用多维数组的线性表示为矩阵分配内存:void matrix=malloc(row\u countcolumn\u columnsize\u of\u element);然后您可以寻址矩阵中的任何元素:((yourtype)&matrix[row*column\u count+column])我经常为人们对不同的做事方式的不宽容感到惊讶。这太没意思了。你在没有解释的情况下投了反对票,这当然很糟糕。也许是因为你从本质上改变了语言,例如
allocate\u mat(2,3,float)
只使用宏进行编译。不过这是一种有趣的方法。@MattPhillips:嗯,C标准本身并不是没有先例。
va_arg()
浮现在脑海中。@Jens:除了第二行是
allocate_mat_sz()
的函数原型,而宏是用于
allocate_mat())
,它扩展为对原型函数的调用。哈,我见过
va.*
构造,但在+1之前从未使用过。你说“没有任何意义”是什么意思?这是typedef的本质!
typedef结构mat{/*matrix*/无符号int c,l;void**matrice}*mat,“下面是
结构材料
的外观,现在创建类型
材料
,它将是指向
结构材料
类型结构的指针。"@ElchononEdelson我的意思是,在typedef后面隐藏指针声明没有任何意义,特别是在这种情况下。它只会使代码错误变得容易和难以阅读。啊。从你说的方式来看,这一点根本不清楚。然而,不管你认为它使代码错误容易和难以阅读,我似乎是这样认为的这是一个相当普遍的习惯用语。@ElchononEdelson软件错误也相当普遍。有太多的糟糕的编程实践被普遍使用,人们可以就此编写整本书。指针结构定义在我看来很有意义,但谢谢你的建议!