- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 incr
函数来将值增加 1
我想让它通用,因为我不想为相同的功能制作不同的功能。
假设我想将 int
、float
、char
递增 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]
最后从temp
到 array[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/
我是一名优秀的程序员,十分优秀!