编译其他使用math.h的C程序

时间:2014-02-06 11:20:01

标签: c compilation compiler-errors

您好我有以下函数名为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    */
    }
  }

}

5 个答案:

答案 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>

需要