如何在C?中定义数组的一般映射操作?
理想情况下我想要像python的地图(函数,数组)~~但是作为一个宏。我相信这会像C ++的std :: transform,但是会在C中,而不是使用迭代器..
(这将是一元操作) 我想的是:
template <class T*, class U*,size_t N>
T* map(T (*func)(U), U* arr,size_t N)
{
T* tmp = (T*)malloc(sizeof(T) * N);
size_t i;
for(i=0;i<N;i++)
{
*(tmp+i) = *func(*(arr+i));
}
}
...但当然模板是用C ++编写的.. 那么我怎么能1)做后者和2)如果可以的话,你能解决上面的代码片段。
由于
答案 0 :(得分:1)
对于这样的模板,有一个相当简单的宏转换;主要的语法皱纹是你不能返回结果数组,把它写成的变量必须是另一个参数。
#define map(func_, input_, output_, type_, n_) do { \
output_ = xmalloc(sizeof(type_) * (n_)); \
size_t i_; \
for (i_ = 0; i_ < (n_); i_++) \
output_[i_] = func_(input_[i_]); \
} while (0)
如果您注意编译器警告,这并不像它看起来那样类型不安全。但是,如果使用此宏的任何实际参数不是简单标识符,则不特别安全。最重要的是,如果任何实际参数都有副作用,那么灾难性会发生。
这可以治愈,因为无法返回结果数组,但只有当你愿意使用GNU扩展时......
#define gnumap(func_, input_, type_, n_) ({ \
__typeof(func_) func__ = (func_); \
__typeof(input_) input__ = (input_), \
output__ = xmalloc(sizeof(type_) * n__); \
__typeof(n_) n__ = (n_), \
i__; \
for (i__ = 0; i__ < n__; i__++) \
output__[i__] = func__(input__[i__]); \
/* return */ output__; \
})
我会在现实生活中做这些吗?可能不是,但有时它确实是最糟糕的可用选项。可以把它想象成用汇编语言重写那个关键内循环的一步。
(xmalloc
,如果您不熟悉它,则是围绕malloc
的用户编写包装器的常规名称,该包装器会成功或崩溃整个程序。我在这里使用它来躲闪如何应对malloc
失败的问题。)
答案 1 :(得分:0)
因此,您可以编写一个函数,该函数将一个函数指针和一个void *
(或char *
)写入数据,以及一个数据大小。
我当然不会只使用宏来执行此操作,但您可能有一个宏,可以执行以下操作:
#define MAP(func, type, arr, size) map(func, sizeof(type), arr, size)
和map
是我上面描述的功能。