C中的常规地图操作

时间:2013-02-08 23:26:16

标签: c

如何在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)如果可以的话,你能解决上面的代码片段。

由于

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是我上面描述的功能。