作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个函数,它接受一个数据 block 和 block 的大小以及一个函数指针作为参数。然后它遍历数据并对数据 block 的每个元素执行计算。以下是我正在做的事情的基本概要:
int myfunction(int* data, int size, int (*functionAsPointer)(int)){
//walking through the data and calculating something
for (int n = 0; n < size; n++){
data[n] = (*function)(data[n]);
}
}
我作为参数传递的函数看起来像这样:
int mycalculation(int input){
//doing some math with input
//...
return input;
}
这工作得很好,但现在我需要将一个额外的变量传递给我的函数指针。沿线的东西
int mynewcalculation(int input, int someVariable){
//e.g.
input = input * someVariable;
//...
return input;
}
有没有一种优雅的方式来实现这一点,同时保持我的整体设计理念?
最佳答案
使它完全通用的常用方法是使用 void*,这当然会导致各种类型安全问题:
int map_function(int* data, int size, int (*f_ptr)(int, void*), void *userdata){
//walking through the data and calculating something
for (int n = 0; n < size; n++){
data[n] = (*f_ptr)(data[n], userdata);
}
}
int simple_calculation(int input, void *userdata) {
// ignore userdata and do some math with input
return input;
}
int calculation_with_single_extra_arg(int input, void *userdata) {
int input2 = * (int*) userdata;
// do some math with input and input2
return input;
}
int calculation_with_many_extra_args(int input, void *userdata) {
my_data_t data = (my_data_t *) userdata;
return input * (input * data->a + data->b) + data->c;
}
int main(int argc, char **argv) {
int array[100];
my_data_t userdata = { 1, 2, 3 };
populate(array, 100);
map_function(data, calculation_with_many_extra_args, &userdata);
}
要传入的任何给定函数都必须具有该原型(prototype),但您可以通过 userdata
推送任何您想要的数据。完全没有类型检查。
您也可以按照 dbingham 的建议使用 va_args;不过这并没有太大区别,因为要映射的函数的原型(prototype)必须是 int(int, va_list)
。
编辑:我赞成 void*
方法。 va_list
无论如何都不会添加任何类型安全,并增加了更多用户错误的可能性(特别是调用 va_end
两次或未正确实现 va_arg
循环) . void* 也没有添加任何额外的代码行;它被干净地传递,用户只是将它取消引用为(希望如此)正确的类型(在一般情况下,这可能是一个结构)。
关于c - C 中的泛型函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2457498/
我是一名优秀的程序员,十分优秀!