我一直在阅读有关以函数作为参数的函数,特别是在 C 中,它们使用函数指针。假设我想实现牛顿拉夫森方法(以简单的方式)来计算非线性方程中的零点。
double derivative(double f(double), double x)
{
double h = 1e-9;
return (f(x + h) - f(x)) / h;
}
double newton_raphson(double f(double), double x0, double tol)
{
double xk, diff;
do
{
xk = x0 - f(x0) / derivative(f, x0);
diff = fabs(xk - x0);
x0 = xk;
} while (diff >= tol);
return xk;
}
因此,为了计算导数的近似值,我需要一个返回双精度值并采用双精度值作为参数的函数。给定其他参数,计算函数的根也是如此。我的问题是,为什么这与将函数参数声明为函数指针不同?例如将输入参数 f 声明为函数指针而不仅仅是函数......
参数f
两者都是指向函数的指针derivative
and newton_raphson
.
double derivative(double f(double), double x) { ... }
完全等于
double derivative(double (*f)(double), double x) { ... }
只是,前者看起来更好 - 通常当你可以省略括号时,你应该这样做。毕竟它们都相当于
double ((((derivative)))(double (((*(f))))(double ((trouble))), double ((x)))) { ... }
我希望只在 IOCCC 中使用。
但是,如果您声明、定义变量(而不是函数参数),则需要使用
double (*f)(double);
as
double f(double);
只是一个函数声明。
6.7.6.3 函数声明符(包括原型)C11 草案 n1570 说:
将参数声明为“函数返回”
类型
” 应调整为“指向
函数返回
类型
”,如 6.3.2.1 所示。
And
6.9.1 函数定义进一步说
[...] 每个参数的类型按照参数类型列表 6.7.6.3 中的描述进行调整;结果类型应该是一个完整的对象
类型。
另外它还有以下示例:
实施例2
为了将一个函数传递给另一个函数,人们可能会说
int f(void);
/* ... */
g(f);
然后定义g
可能会读
void g(int (*funcp)(void))
{
/* ... *
(*funcp)(); /* or funcp(); ... */
}
或者,等价地,
void g(int func(void))
{
/* ... */
func(); /* or (*func)(); ... */
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)