您好我正在制作一些程序来寻找不同正弦函数的解决方案。 我想犯罪(2x),sin(4x),sin(6x),...... sin(12x)并将它们存储到数组中,以便我可以在给定的时间间隔内测试每个函数的解。/ p>
下面'代码......
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double));
int main()
{
double x, x0 = 2.0, xf = 4.0, tolerance = FLT_EPSILON;
int status, i, j;
double (*pf[6])(double);
for (i = 1; i < 7; i++)
{
pf[i] = sin(2 * i * x);
// error : cannot assign double value to double(*) (double) entity
// How to make functions like sin(2x), sin(4x), .. etc??
status = bisect(&x, x0, xf, tolerance, pf[i]);
我创建了bisect()函数来查找给定函数返回0的点。
二分功能低于主要功能。 x0是起点,xf是终点,我设置了检查错误的容差。平分函数在for循环中使用中间值定理。
我想通过在for循环中调用bisect函数找到解决方案,并使用* pf [i]传递正弦函数。
if (status == -1)
printf("Error : bisect() failed, invalid tolerance\n");
else if(status == -2)
printf("Error : bisect() failed, invalid end points\n");
else
printf("x = %f, sin(x) = %g\n", x, pf[i](x));
}
return 0;
}
int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double))
{
double xleft = x0, fleft;
double xright = xf;
double xmid, fmid;
if (tolerance <= 0.0)
return -1;
fleft = func(x0);
if (fleft * func(xf) > 0.0)
return -2;
xmid = (xleft+xright) /2.0;
fmid = func(xmid);
while (fabs(fmid) > tolerance)
{
if (fleft * fmid <= 0)
{
xright = xmid;
}
else
{
xleft = xmid;
fleft = fmid;
}
xmid = (xleft + xright) / 2.0;
fmid = func(xmid);
}
*x = xmid;
return 0;
}
很容易找到罪,cos等的解决方案但是罪(2x),罪(4x)等等?我怎样才能将这些功能存储在* pf []中? (函数指针数组)
任何建议都会有所帮助。
答案 0 :(得分:3)
在C语言中,如果不创建包含原始sin
函数的多个函数,则无法执行您想要的操作。
也许像
double sin2(double value)
{
return sin(2 * value);
}
double sin4(double value)
{
return sin(4 * value);
}
// Etc...
int main(void)
{
double (*pf[6])(double) = {
sin2, sin4, ...
};
for (int i = 0; i < 6; ++i)
{
printf("%f\n", pf[i](0.5));
}
}
答案 1 :(得分:0)
可悲的是,C不支持完全成熟的闭包,这就是你想要的。
但是,您应该能够在程序中定义任何自定义函数以获取double
并返回double
,并将其传递给您的bisect函数。
例如:
double some_function(double x) {
// You can do anything you like, as long as you return a double.
return sin(2 * x);
}
在您的情况下,为i
的每个值单独指定一个自定义函数可能有点乏味,但您可以通过使用宏来消除一些重复,例如:
#define DEFINE_SIN_POLY(i) double sin_poly_##i##(double x) { \
return sin(2 * i * x); \
}
DEFINE_SIN_POLY(2);
DEFINE_SIN_POLY(3); // etc.
// then, you can simply access these functions as
sin_poly_2, sin_poly_3, etc.
然而,这有点难看。如果您使用C ++,您可以利用更高级的功能,例如函数类型,lambdas等,使您的代码更简洁,几乎不会损失性能。
答案 2 :(得分:0)
您需要动态创建函数,这些函数具有某些参数的内存。您可以将这些参数设为全局,也可以创建所谓的closure。
即使C本身不支持这样的事情,你也可以通过在堆上创建具有所需行为的新函数来模拟它。有些库可以帮助您实现这一目标。
libffi是一个允许你在C中创建闭包的库,尽管它是一种非常先进的技术。
文档提供了一些示例:http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Closure-Example.html
答案 3 :(得分:0)
错误的原因是
{"even": true}
调用pf[i] = sin(2 * i * x);
函数,其参数等于sin()
的当前值。结果是该特定值的正弦值,而不是函数。
基本上,标准C不支持闭包。
获得所需效果的最简单方法是改变2*i*x
的规范,而不是试图在循环中直接或间接创建一组函数,而不是
bisect()
添加额外参数
int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double))
并且,在调用int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double), double factor)
的每个位置,更改为func(something)
。例如,将func(something*factor)
更改为fmid = func(xmid)
。
然后在调用者(fmid = func(xmid * factor)
)中更改循环
main()
到
for (i = 1; i < 7; i++)
{
pf[i] = sin(2 * i * x);
// error : cannot assign double value to double(*) (double) entity
// How to make functions like sin(2x), sin(4x), .. etc??
status = bisect(&x, x0, xf, tolerance, pf[i]);
请注意,这完全不需要数组for (i = 1; i < 7; i++)
{
// How to make functions like sin(2x), sin(4x), .. etc
status = bisect(&x, x0, xf, tolerance, sin, 2*i);
。它的工作原理是将pf
的值传递给函数2*i
,然后可以使用它。
但是,更一般地说,您需要花时间阅读C教科书。试图通过类比Python来学习C会导致各种各样的问题,因为Python支持很多功能(比如这种情况下的闭包),而C则没有,并且在C中不能轻易模仿它们。它们是非常不同的语言和通常需要非常不同的方法来构建程序。