gpt4 book ai didi

c - 在 C 中的数组上实现通用 'map' 函数

转载 作者:太空狗 更新时间:2023-10-29 16:46:29 25 4
gpt4 key购买 nike

我在数组上实现通用“映射”函数时遇到困难。我从以下草稿开始:

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' 之前转换为 (char *) - 但我现在失去了动力并且无法提出解决方案。 (我在学习C的过程中就是这样做的)

我的基本原理是获取'f'的结果,然后逐字节复制到dest[i]。

你能给我一些提示吗?

最佳答案

您的第一个问题是您在几个表达式中做的太多了。您需要将其分解。

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 调用的结果?这是完全没有必要的。

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];
}
}
}

现在是你的第三个问题。您将指针传递给 - 但仅传递给 char。您不会通过 void*。这意味着您的函数不能是通用的 - f 不能应用于任何东西。我们需要一个 void*s 数组,这样函数就可以接受任何类型作为参数。我们还需要将类型的大小作为参数,以便我们知道沿着 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;
}
}

我们还有一个问题——temp的内存。我们不释放它。我们也没有将用户数据参数传递给 f,这将允许它返回我们不需要释放的堆分配内存。 f 可以工作的唯一方法是它返回一个静态缓冲区。

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 几乎可以对它喜欢的任何东西进行操作并保持它需要的任何状态。但是我们仍然没有释放缓冲区。现在,f 返回一个简单的结构,告诉我们是否需要释放缓冲区。这也允许我们在不同的 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 循环吗?您尝试替换的代码比调用您的函数的代码更简单,而且可能更高效,而且绝对更强大(例如,他们可以使用 continue/break)。

不仅如此,C 语言对于这种工作来说真的很糟糕。 C++要好得多。例如,将一个函数应用于数组的每个成员是非常简单的。

关于c - 在 C 中的数组上实现通用 'map' 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4047431/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com