在以上C数组实现generical“地图”功能 [英] Implementing a generical 'map' function over arrays in C

查看:141
本文介绍了在以上C数组实现generical“地图”功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有在实施阵列一个通用的'地图'功能的困难。
我开始与以下草案:

I'm having difficulties implementing a generic 'map' function over arrays. I started with the following draft:

void MapArray(void * src, void * dest, void * (f)(void *), size_t n, size_t elem)
{
   unsigned int i = 0, j = 0;
   void * temp = malloc(elem);

   for(i = 0; i<n, i++)
   {
      temp = (f)((char *) src) + i));
      for(j = 0; j < elem; j++)
      {
         *(((char *) dest) + i) = *(((char *) temp) + i);
      }
   }
   free(temp);
}

我明白为什么这不是正确的 - 把它给'F'之前,我正在铸造(字符*) - 但现在我失去动力,不能拿出一个解决方案。 (我在学习C的过程中这样做)

I understand why it's not correct - i'm casting to (char *) before giving it to 'f' - but i'm now demotivated and can't come up with a solution. (I'm doing this in the process of learning C)

我的理由是通过字节以获得f和,字节的结果,将它复制到dest [I]。

My rationale was to obtain the result of 'f' and, byte by byte, copy it to dest[i].

您可以给我任何暗示?

推荐答案

您的第一个问题是,你正在做的方式数前pressions太多。你需要打破它。

Your first problem is that you're doing WAY too much in a few expressions. You need to break it down.

void MapArray(void * src, void * dest, void * (f)(void *), size_t n, size_t elem)
{
   unsigned int i = 0, j = 0;
   void * temp = malloc(elem);

   char* csrc = (char*)src;
   char* cdest = (char*)dest;
   char* ctemp = (char*)temp;
   for(i = 0; i<n; i++)
   {
       csrc++;
       cdest++;
       ctemp++;
       temp = f(csrc);
       for(j = 0; j < elem; j++)
       {
           cdest[i] = ctemp[i];
       }
   }
   free(temp);
}

现在你的第二个问题。你MALLOC一个缓冲区,然后你..分配给该指针?反复?然后只自由的最后一架F调用的结果呢?这是完全不必要的。

Now your second problem. You malloc a buffer, then you .. assign to that pointer? Repeatedly? Then free only the last f call's result? This is totally unnecessary.

void MapArray(void * src, void * dest, void * (f)(void *), size_t n, size_t elem)
{
   unsigned int i = 0, j = 0;

   char* csrc = (char*)src;
   char* cdest = (char*)dest;
   for(i = 0; i<n; i++)
   {
       csrc++;
       cdest++;
       char* ctemp = (char*)f(csrc);
       for(j = 0; j < elem; j++)
       {
           cdest[i] = ctemp[i];
       }
   }
}

现在你的第三个问题。但只有字符 - 你传递一个指针。你不是在真空传递*。这意味着,你的函数不能通用 - F无法被应用到任何东西。我们需要的void *的数组中,这样的功能可以采取任何类型作为参数。我们还需要采取类型的大小作为一个参数,所以我们知道多远沿着DEST移动。

Now your third problem. You pass a pointer in - but only to char. You don't pass in a void*. This means that your function can't be generic - f can't be applied to anything. We need an array of void*s, so that the function can take any type as argument. We also need to take the size of the type as an argument so we know how far to move along dest.

void MapArray(void ** src, void * dest, void * (f)(void *), size_t n, size_t sizeofT)
{
    for(unsigned int i = 0; i < n; i++) {
        void* temp = f(src[n]);
        memcpy(dest, temp, sizeofT);
        dest = (char*)dest + sizeofT;
    }
}

我们还有另外一个问题 - 临时的内存。我们不释放它。我们也不传递用户数据参数到f中,这将允许返回堆上分配的内存,我们并不需要释放。其中,f可以工作的唯一方法是,如果它返回一个静态缓冲区。

We still have another problem - the memory of temp. We don't free it. Nor do we pass a user data argument into f, which would allow it to return heap-allocated memory that we don't need to free. The only way in which f can work is if it returned a static buffer.

void MapArray(void ** src, void * dest, void * (f)(void *, void*), void* userdata, size_t n, size_t sizeofT)
{
    for(unsigned int i = 0; i < n; i++) {
        void* temp = f(src[n], userdata);
        memcpy(dest, temp, sizeofT);
        dest = (char*)dest + sizeofT;
    }
}

现在F能够在pretty无论多喜欢它按住它需要的任何状态下工作。但是,我们仍然不释放缓冲区。现在,女返回一个简单的结构,它告诉我们,如果我们需要释放缓冲区。这也让我们自由或不自由F上的不同的调用缓存。

Now f can operate on pretty much whatever it likes and hold whatever state it needs. But we still don't free the buffer. Now, f returns a simple struct that tells us if we need to free the buffer. This also allows us to free or not free the buffer on different calls of f.

typedef struct {
    void* data;
    int free;
} freturn;

void MapArray(void ** src, void * dest, freturn (f)(void *, void*), void* userdata, size_t n, size_t sizeofT)
{
    for(unsigned int i = 0; i < n; i++) {
        freturn thisreturn = f(src[n], userdata);
        void* temp = thisreturn.data;
        memcpy(dest, temp, sizeofT);
        dest = (char*)dest + sizeofT;
        if (thisreturn.free)
            free(temp);
    }
}

不过,我还是不明白这个功能的目的。所有这一切都更换一次简单的for循环?你正在试图取代code比code简单的调用你的函数,而且可能更有效,绝对更强大(他们可以继续使用/休息,例如)。

However, I still don't understand the purpose of this function. All of this to replace a simple for loop? The code that you're trying to replace is simpler than the code to call your function, and probably more efficient, and definitely more powerful (they can use continue/break, for example).

不仅如此,C实在太烂了这样的工作。 C ++是更好的。这是pretty琐碎有一个函数应用到阵列中的每个成员,例如

More than that, C really sucks for this kind of work. C++ is far better. It's pretty trivial there to apply a function to each member of an array, for example.

这篇关于在以上C数组实现generical“地图”功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆