gpt4 book ai didi

c - 如何在 c 中使用 void * 创建泛型函数?

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

我有一个 incr 函数来将值增加 1我想让它通用,因为我不想为相同的功能制作不同的功能。

假设我想将 intfloatchar 递增 1

void incr(void *vp)
{
(*vp)++;
}

但我知道的问题是取消引用 void 指针是未定义的行为。有时它可能会报错:Invalid use of void expression

我的主要功能是:

int main()
{

int i=5;
float f=5.6f;
char c='a';

incr(&i);
incr(&f);
incr(&c);

return 0;
}

问题是如何解决这个问题?有没有办法只在 C

中解决它

我必须为每个数据类型定义 incr() 吗?如果是,那么 void *

有什么用

同样的问题与 swap()sort() 。我想交换和排序具有相同功能的所有类型的数据。

最佳答案

您可以将第一个实现为宏:

#define incr(x) (++(x))

当然,如果您不小心,这可能会产生令人不快的副作用。它是关于 C 提供的唯一方法,用于将相同的操作应用于各种类型中的任何一种。特别是,由于宏是使用文本替换实现的,当编译器看到它时,您只有文字代码 ++whatever;,它可以应用 ++ 适合您提供的项目类型。使用指向 void 的指针,您对实际类型知之甚少(如果有的话),因此您不能对该数据进行太多直接操作。

void * 通常在相关函数不需要知道所涉及数据的确切类型时使用。在某些情况下(例如,qsort),它使用回调函数来避免了解数据的任何细节。

因为它同时进行排序和交换,让我们更详细地看一下 qsort。它的签名是:

void qsort(void *base, size_t nmemb, size_t size,
int(*cmp)(void const *, void const *));

因此,第一个是您询问的 void * -- 指向要排序的数据的指针。第二个告诉 qsort 数组中元素的数量。第三,数组中每个元素的大小。最后一个是指向可以比较单个项目的函数的指针,因此 qsort 不需要知道如何做。例如,在 qsort 内部的某个地方会有一些类似的代码:

// if (base[j] < base[i]) ...
if (cmp((char *)base+i, (char *)base+j) == -1)

同样,要交换两个项目,它通常会有一个本地数组用于临时存储。然后它将字节从 array[i] 复制到它的临时文件,然后从 array[j] 复制到 array[i] 最后从temparray[j]:

char temp[size];

memcpy(temp, (char *)base+i, size); // temp = base[i]
memcpy((char *)base+i, (char *)base+j, size); // base[i] = base[j]
memcpy((char *)base+j, temp, size); // base[j] = temp

关于c - 如何在 c 中使用 void * 创建泛型函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13469381/

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