我一直在阅读关于函数作为参数的函数,特别是在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声明为函数指针,而不仅仅是函数.
发布于 2016-04-12 16:06:07
参数f在derivative和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);作为
double f(double);只是一个函数声明。
6.7.6.3 C11草案n1570的函数声明器(包括原型)说:
将参数声明为“函数返回类型”应调整为“指向函数返回类型的指针”,如6.3.2.1所示。
6.9.1函数定义进一步指出
..。每个参数的类型按照6.7.6.3中对参数类型列表的描述进行调整;结果类型应该是一个完整的对象类型。
此外,它还有以下示例:
示例2 要将一个函数传递给另一个函数,人们可能会说 /* . */ g(f); 然后,
g的定义可能会读到 { /* .*(*函子)();/*或函式();. */ } 或等效的 { /* . */ func();/*或(*func)();…*/ }
发布于 2016-04-12 17:31:42
与普通数据指针一样,函数指针可以作为参数传递,也可以从函数返回。函数的名称包含函数的地址。
我的问题是,为什么这与将函数参数声明为函数指针不同?例如,将输入参数f声明为函数指针,而不仅仅是函数.
答案是,编译器将将这两种表单视为相同的。但是,为了代码的可重用性,可以使用示例代码所具有的声明类型,即,
double derivative(double f(double), double x) { ... }即使在C中,下面给出的函数定义也将被解释为相同的-
void foo(int a[]) // or int a[10]
{
...
}
void foo(int *a)
{
...
}https://stackoverflow.com/questions/36578503
复制相似问题