我有一个自动为矩阵结构创建结构的函数。该结构体具有三个属性:x 大小、y 大小和指向双精度二维数组的指针。
typedef struct Matrix
{
uint16_t sizeX;
uint16_t sizeY;
double* data;
} Matrix;
我还有一个辅助函数,用于自动填充结构体的字段
Matrix _create_matrix(uint16_t sizeY, uint16_t sizeX, double numbers[][sizeX])
{
double *data = calloc(sizeX*sizeY, sizeof(double));
if(!data)
{
return create_empty_matrix();
}
memcpy(data, numbers, sizeX * sizeY * sizeof(*data));
return (Matrix){ .sizeX = sizeX,
.sizeY = sizeY,
.data = data }; // returns matrix object
}
为了避免输入数据的维度,我使用一个宏来计算矩阵的大小。
#define create_matrix(data) ({ uint16_t sizeY = sizeof(data)/sizeof(data[0]); \
uint16_t sizeX = sizeof(data)/sizeof(double)/sizeY; \
_create_matrix(sizeY, sizeX, data); })
但是,我听说宏不应该真正使用,因为它们缺乏类型检查等。在 C 中是否可以在不使用宏的情况下拥有这样的辅助函数?
是的,通过将大小信息作为参数传递给辅助函数,可以在不使用宏的情况下实现相同的功能。您可以在函数本身中计算维度,这种方法通常更加类型安全和可读。
以下是如何修改辅助函数以实现此目的的示例:
c代码
Matrix create_matrix(uint16_t sizeY, uint16_t sizeX, double numbers[][sizeX])
{
double *data = calloc(sizeX * sizeY, sizeof(double));
if (!data)
{
return create_empty_matrix();
}
// Copy data element by element
for (uint16_t i = 0; i < sizeY; i++)
{
for (uint16_t j = 0; j < sizeX; j++)
{
data[i * sizeX + j] = numbers[i][j];
}
}
return (Matrix){.sizeX = sizeX, .sizeY = sizeY, .data = data};
}
然后就可以直接调用这个函数了,不需要宏:
c代码
double myData[][3] = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}};
矩阵 myMatrix = create_matrix(3, 3, myData);
这种方法提供了更好的类型安全性,并避免了与宏相关的潜在陷阱。您仍然可以在调用函数时计算数组的维度,但计算现在是函数本身的一部分。