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

War*_*250 5 c compiler-errors compilation

嗨我有以下函数叫做zeroin我想用Cpp文件编译和链接但是我无法通过编译c文件的第一步.该函数名为zeroin.c,我从这里获得.我把文件放在它自己的目录中,cd给它,因为它使用math.h我使用带有-lm标志的gcc来确保链接库.

gcc -Wall -O zeroin.c -o zeroin -lm
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

我已经在下面包含了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    */
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

感谢大家的建议,我已将格式更改为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]
Run Code Online (Sandbox Code Playgroud)

我可能还有另一个我需要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    */
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 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     */
{
Run Code Online (Sandbox Code Playgroud)

至:

double zeroin(double ax, double bx, double (*f)(double), double tol)
{
Run Code Online (Sandbox Code Playgroud)

肯定有一种方法可以gcc接受旧的风格,但除非你担心来自上游变化的合并冲突,你也可以只更新它:-)


Mik*_*our 8

看起来文件名有一个大写的扩展名,.C这使得GCC认为它是C++而不是C.代码是古老的C方言(称为"K&R风格"),它与C++不兼容.

将文件重命名为zeroin.c,或在命令行中指定语言-x c.

或者,如果您需要使用不了解K&R语法的编译器,您可以更改函数头以使用现代语法:

double zeroin(double ax, double bx, double(*f)(double x), double tol)
{
    // code here
}
Run Code Online (Sandbox Code Playgroud)

剩下的问题是使用EPSILON; 在一个现代的C库中,这就是所谓的DBL_EPSILON.