您好我有以下函数名为zeroin我想编译并链接到一个Cpp文件但我无法通过编译c文件的第一步。该函数名为zeroin.c,我是从here获得的。我把文件放在它自己的目录中,cd给它,因为它使用math.h我使用带有-lm标志的gcc来确保链接库。
gcc -Wall -O zeroin.c -o zeroin -lm
但是我收到以下错误:
zeroin.C:50:15: error: 'ax' was not declared in this scope
zeroin.C:50:18: error: 'bx' was not declared in this scope
zeroin.C:50:21: error: 'f' was not declared in this scope
zeroin.C:50:23: error: 'tol' was not declared in this scope
zeroin.C:50:26: error: expression list treated as compound expression in initialiser [-fpermissive]
zeroin.C:51:1: error: expected ',' or ';' before 'double'
zeroin.C:55:1: error: expected unqualified-id before '{' token
我已经包含了下面的C代码函数的代码 - 我真的不太了解C并且只是尝试编译它以便使用它来查找我在C ++文件中的函数的根。我该如何解决这些错误?
谢谢, 本。
#include "math.h"
double zeroin(ax,bx,f,tol) /* An estimate to the root */
double ax; /* Left border | of the range */
double bx; /* Right border| the root is seeked*/
double (*f)(double x); /* Function under investigation */
double tol; /* Acceptable tolerance */
{
double a,b,c; /* Abscissae, descr. see above */
double fa; /* f(a) */
double fb; /* f(b) */
double fc; /* f(c) */
a = ax; b = bx; fa = (*f)(a); fb = (*f)(b);
c = a; fc = fa;
for(;;) /* Main iteration loop */
{
double prev_step = b-a; /* Distance from the last but one*/
/* to the last approximation */
double tol_act; /* Actual tolerance */
double p; /* Interpolation step is calcu- */
double q; /* lated in the form p/q; divi- */
/* sion operations is delayed */
/* until the last moment */
double new_step; /* Step at this iteration */
if( fabs(fc) < fabs(fb) )
{ /* Swap data for b to be the */
a = b; b = c; c = a; /* best approximation */
fa=fb; fb=fc; fc=fa;
}
tol_act = 2*EPSILON*fabs(b) + tol/2;
new_step = (c-b)/2;
if( fabs(new_step) <= tol_act || fb == (double)0 )
return b; /* Acceptable approx. is found */
/* Decide if the interpolation can be tried */
if( fabs(prev_step) >= tol_act /* If prev_step was large enough*/
&& fabs(fa) > fabs(fb) ) /* and was in true direction, */
{ /* Interpolatiom may be tried */
register double t1,cb,t2;
cb = c-b;
if( a==c ) /* If we have only two distinct */
{ /* points linear interpolation */
t1 = fb/fa; /* can only be applied */
p = cb*t1;
q = 1.0 - t1;
}
else /* Quadric inverse interpolation*/
{
q = fa/fc; t1 = fb/fc; t2 = fb/fa;
p = t2 * ( cb*q*(q-t1) - (b-a)*(t1-1.0) );
q = (q-1.0) * (t1-1.0) * (t2-1.0);
}
if( p>(double)0 ) /* p was calculated with the op-*/
q = -q; /* posite sign; make p positive */
else /* and assign possible minus to */
p = -p; /* q */
if( p < (0.75*cb*q-fabs(tol_act*q)/2) /* If b+p/q falls in [b,c]*/
&& p < fabs(prev_step*q/2) ) /* and isn't too large */
new_step = p/q; /* it is accepted */
/* If p/q is too large then the */
/* bissection procedure can */
/* reduce [b,c] range to more */
/* extent */
}
if( fabs(new_step) < tol_act ) /* Adjust the step to be not less*/
if( new_step > (double)0 ) /* than tolerance */
new_step = tol_act;
else
new_step = -tol_act;
a = b; fa = fb; /* Save the previous approx. */
b += new_step; fb = (*f)(b); /* Do step to a new approxim. */
if( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) )
{ /* Adjust c for it to have a sign*/
c = a; fc = fa; /* opposite to that of b */
}
}
}
- 编辑 -
感谢大家的建议,我已将格式更改为ANSI格式并将EPSILON更改为DBL_EPSILON,并将#include“math.h”改为#include - 更新后的函数(包括在下面)。但是,如果我这次尝试编译:
$gcc -Wall zeroin.c -o zeroin -lm
zeroin.c: In function 'zeroin':
zeroin.c:78:17: error: 'DBL_EPSILON' undeclared (first use in this function)
zeroin.c:78:17: note: each undeclared identifier is reported only once for each function it appears in
zeroin.c:116:7: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]
如果说DBL_EPSILON没有定义,我可能还需要另一个库吗?
谢谢, 本。
#include <math.h>
double zeroin(double ax, double bx, double(*f)(double x), double tol) /* An estimate to the root */
{
double a,b,c; /* Abscissae, descr. see above */
double fa; /* f(a) */
double fb; /* f(b) */
double fc; /* f(c) */
a = ax; b = bx; fa = (*f)(a); fb = (*f)(b);
c = a; fc = fa;
for(;;) /* Main iteration loop */
{
double prev_step = b-a; /* Distance from the last but one*/
/* to the last approximation */
double tol_act; /* Actual tolerance */
double p; /* Interpolation step is calcu- */
double q; /* lated in the form p/q; divi- */
/* sion operations is delayed */
/* until the last moment */
double new_step; /* Step at this iteration */
if( fabs(fc) < fabs(fb) )
{ /* Swap data for b to be the */
a = b; b = c; c = a; /* best approximation */
fa=fb; fb=fc; fc=fa;
}
tol_act = 2*DBL_EPSILON*fabs(b) + tol/2;
new_step = (c-b)/2;
if( fabs(new_step) <= tol_act || fb == (double)0 )
{
return b; /* Acceptable approx. is found */
}
/* Decide if the interpolation can be tried */
if( fabs(prev_step) >= tol_act /* If prev_step was large enough*/
&& fabs(fa) > fabs(fb) ) /* and was in true direction, */
{ /* Interpolatiom may be tried */
register double t1,cb,t2;
cb = c-b;
if( a==c ) /* If we have only two distinct */
{ /* points linear interpolation */
t1 = fb/fa; /* can only be applied */
p = cb*t1;
q = 1.0 - t1;
}
else /* Quadric inverse interpolation*/
{
q = fa/fc; t1 = fb/fc; t2 = fb/fa;
p = t2 * ( cb*q*(q-t1) - (b-a)*(t1-1.0) );
q = (q-1.0) * (t1-1.0) * (t2-1.0);
}
if( p>(double)0 ) /* p was calculated with the op-*/
q = -q; /* posite sign; make p positive */
else /* and assign possible minus to */
p = -p; /* q */
if( p < (0.75*cb*q-fabs(tol_act*q)/2) /* If b+p/q falls in [b,c]*/
&& p < fabs(prev_step*q/2) ) /* and isn't too large */
new_step = p/q; /* it is accepted */
/* If p/q is too large then the */
/* bissection procedure can */
/* reduce [b,c] range to more */
/* extent */
}
if( fabs(new_step) < tol_act ) /* Adjust the step to be not less*/
if( new_step > (double)0 ) /* than tolerance */
new_step = tol_act;
else
new_step = -tol_act;
a = b; fa = fb; /* Save the previous approx. */
b += new_step; fb = (*f)(b); /* Do step to a new approxim. */
if( (fb > 0 && fc > 0) || (fb < 0 && fc < 0) )
{ /* Adjust c for it to have a sign*/
c = a; fc = fa; /* opposite to that of b */
}
}
}
答案 0 :(得分:8)
此代码使用古老的预标准功能签名样式,参数列表后面的参数类型。
更改
double zeroin(ax,bx,f,tol) /* An estimate to the root */
double ax; /* Left border | of the range */
double bx; /* Right border| the root is seeked*/
double (*f)(double x); /* Function under investigation */
double tol; /* Acceptable tolerance */
{
为:
double zeroin(double ax, double bx, double (*f)(double), double tol)
{
肯定有办法让gcc
接受旧样式,但除非你担心来自上游变化的合并冲突,否则你也可以更新它: - )
答案 1 :(得分:8)
看起来文件名有一个大写的扩展名.C
,这使得GCC认为它是C ++而不是C.代码是古老的C方言(称为“K&amp; R风格”),与C ++不兼容。
将文件重命名为zeroin.c
,或使用-x c
在命令行中指定语言。
或者,如果您需要使用不理解K&amp; R语法的编译器,您可以更改函数头以使用现代语法:
double zeroin(double ax, double bx, double(*f)(double x), double tol)
{
// code here
}
剩下的问题是使用EPSILON
;在现代C库中,称为DBL_EPSILON
。
答案 2 :(得分:4)
我认为这是非常古老的C代码。以这种方式声明zeroin
函数的语法
double zeroin(ax,bx,f,tol) /* An estimate to the root */
double ax; /* Left border | of the range */
double bx; /* Right border| the root is seeked*/
double (*f)(double x); /* Function under investigation */
double tol; /* Acceptable tolerance */
已经过时了,现已弃用,因此编译器无法理解它。将其更改为:
double zeroin(double ax, double bx, double (*f)(double x), double tol)
答案 3 :(得分:1)
您正在使用K&amp; R风格的功能声明
尝试使用ANSI标准样式:
double zeroin(double ax,double bx, double (*f)(double), double tol);
答案 4 :(得分:0)
如果DBL_EPSILON说它没有定义,我可能还需要另一个库吗?
也许
#include <float.h>
需要