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软件错误也相当普遍。有太多的糟糕的编程实践被普遍使用,人们可以就此编写整本书。指针结构定义在我看来很有意义,但谢谢你的建议!