警告:我是一名 C++ 开发人员,对 C 知识知之甚少,因此接下来的所有内容都可能是单一的 C。
作为KerrekSB said,您需要在函数中携带一些状态。这对于原始函数是不可能的,但您可以定义一个携带状态的结构并添加一个与该结构一起使用的函数。这显然具有失去良好的函数调用语法的缺点。我举了一个例子:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef double (*raw_fptr)(double);
struct real_function;
typedef double (*evaluate_function)(struct real_function*, double);
struct real_function {
evaluate_function evaluate;
};
typedef struct real_function real_function;
double evaluate(real_function *f, double x) {
if(f) {
return f->evaluate(f, x);
}
return NAN;
}
struct raw_real_function {
real_function real_function_base;
raw_fptr raw_function;
};
typedef struct raw_real_function raw_real_function;
double evaluate_raw_real_function(real_function *f_base, double x) {
if(f_base) {
raw_real_function *f = (raw_real_function*)f_base;
return f->raw_function(x);
}
return NAN;
}
raw_real_function make_raw_real_function(raw_fptr function) {
raw_real_function result;
result.raw_function = function;
result.real_function_base.evaluate = evaluate_raw_real_function;
return result;
}
struct derive_real_function {
real_function real_function_base;
real_function *function_to_derive;
};
typedef struct derive_real_function derive_real_function;
double derive(real_function *f_base, double x) {
derive_real_function *f = (derive_real_function*)f_base;
double epsilon = 1e-3;
double upper = evaluate(f->function_to_derive, x+epsilon);
double lower = evaluate(f->function_to_derive, x-epsilon);
double result = (upper - lower)/(2.0*epsilon);
return result;
}
derive_real_function make_derivative(real_function * function_to_derive) {
derive_real_function result;
result.real_function_base.evaluate = derive;
result.function_to_derive = function_to_derive;
return result;
}
double x_cubed(double x) {
return x * x * x;
}
int main(int argc, char **argv) {
raw_real_function x_cubed_wrapped = make_raw_real_function(x_cubed);
derive_real_function derived = make_derivative(&x_cubed_wrapped.real_function_base);
derive_real_function derived_twice = make_derivative(&derived.real_function_base);
double x = atof(argv[1]);
double derivative = evaluate(&derived.real_function_base, x);
double second_derivative = evaluate(&derived_twice.real_function_base, x);
printf("derivative of x^3 at %f = %f\n", x, derivative);
printf("second derivative of x^3 at %f = %f\n", x, second_derivative);
return 0;
}
请参阅(由于输入限制,略有变化)运行here。
它是如何工作的?我用结构real_function、raw_real_function 和derive_real_function 伪造了一些继承来生成虚函数调用。 struct real_function 用作仅包含条目evaluate 的虚函数表的容器。此函数指针指向“派生”结构的相关评估函数:
raw_real_function 实例指向evaluate_raw_real_function(在make_raw_real_function 中初始化。derive_real_function 实例将evaluate 指向derive(在make_derivative 中初始化)。
在real_function_base 成员上调用evaluate 时,它将调用关联的评估函数,该函数将real_function* 转换为其关联的结构指针,并使用该信息执行所需的操作。
由于一切都只是一个real_function*,我们可以随意将它们链接起来,但需要将“普通”函数转换为real_function格式,这就是make_raw_real_function所做的。