c++ - 从 C 到 C++ : function was not declared in this scope

标签 c++ c

我从 C 库导入一些方法以在我的 C++ 主代码中使用它们,但出现编译错误:

$ make
g++ -c main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:419:67: error: ‘kmedoids’ was not declared in this scope
 kmedoids(class_num, N, distanceMatrix, 1, clusterid, error, ifound);
                                                                   ^
main.cpp: In function ‘void kmedoids(int, int, double**, int, int*, double*, int*)’:
main.cpp:537:64: error: ‘randomassign’ was not declared in this scope
     if (npass!=0) randomassign(nclusters, nelements, tclusterid);
                                                                ^
main.cpp:550:42: error: ‘getclustermedoids’ was not declared in this scope
                         centroids, errors);
                                          ^
main.cpp: In function ‘void randomassign(int, int, int*)’:
main.cpp:644:20: error: ‘binomial’ was not declared in this scope
   j = binomial(n, p);
                    ^
main.cpp:654:40: error: ‘uniform’ was not declared in this scope
 { j = (int) (i + (nelements-i)*uniform());
                                        ^
main.cpp: In function ‘int binomial(int, double)’:
main.cpp:704:24: error: ‘uniform’ was not declared in this scope
     double u = uniform();
                        ^
main.cpp:732:26: error: ‘uniform’ was not declared in this scope
       double u = uniform();
                          ^
make: *** [main.o] Error 1

这是我的代码的最后一部分,其中包含新的 C 方法:

#include "profileManager.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <limits.h>
#include <float.h>
#include <time.h>

int main(int argc, char *argv[])
{
//......PREVIOUS CODE.......

kmedoids(class_num, N, distanceMatrix, 1, clusterid, error, ifound);

    return 0;
}



//NEW C METHODS
void kmedoids (int nclusters, int nelements, double** distmatrix,
  int npass, int clusterid[], double* error, int* ifound)
{ int i, j, icluster;
  int* tclusterid;
  int* saved;
  int* centroids;
  double* errors;
  int ipass = 0;

  if (nelements < nclusters)
  { *ifound = 0;
    return;
  } /* More clusters asked for than elements available */

  *ifound = -1;

  /* We save the clustering solution periodically and check if it reappears */
  saved = (int*)malloc(nelements*sizeof(int));
  if (saved==NULL) return;

  centroids = (int*)malloc(nclusters*sizeof(int));
  if(!centroids)
  { free(saved);
    return;
  }

  errors = (double*)malloc(nclusters*sizeof(double));
  if(!errors)
  { free(saved);
    free(centroids);
    return;
  }

  /* Find out if the user specified an initial clustering */
  if (npass<=1) tclusterid = clusterid;
  else
  { tclusterid = (int*)malloc(nelements*sizeof(int));
    if(!tclusterid)
    { free(saved);
      free(centroids);
      free(errors);
      return;
    }
  }

  *error = DBL_MAX;
  do /* Start the loop */
  { double total = DBL_MAX;
    int counter = 0;
    int period = 10;

    if (npass!=0) randomassign(nclusters, nelements, tclusterid);
    while(1)
    { double previous = total;
      total = 0.0;

      if (counter % period == 0) /* Save the current cluster assignments */
      { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i];
        if (period < INT_MAX / 2) period *= 2;
      }
      counter++;

      /* Find the center */
      getclustermedoids(nclusters, nelements, distmatrix, tclusterid,
                        centroids, errors);

      for (i = 0; i < nelements; i++)
      /* Find the closest cluster */
      { double distance = DBL_MAX;
        for (icluster = 0; icluster < nclusters; icluster++)
        { double tdistance;
          j = centroids[icluster];
          if (i==j)
          { distance = 0.0;
            tclusterid[i] = icluster;
            break;
          }
          tdistance = (i > j) ? distmatrix[i][j] : distmatrix[j][i];
          if (tdistance < distance)
          { distance = tdistance;
            tclusterid[i] = icluster;
          }
        }
        total += distance;
      }
      if (total>=previous) break;
      /* total>=previous is FALSE on some machines even if total and previous
       * are bitwise identical. */
      for (i = 0; i < nelements; i++)
        if (saved[i]!=tclusterid[i]) break;
      if (i==nelements)
        break; /* Identical solution found; break out of this loop */
    }

    for (i = 0; i < nelements; i++)
    { if (clusterid[i]!=centroids[tclusterid[i]])
      { if (total < *error)
        { *ifound = 1;
          *error = total;
          /* Replace by the centroid in each cluster. */
          for (j = 0; j < nelements; j++)
            clusterid[j] = centroids[tclusterid[j]];
        }
        break;
      }
    }
    if (i==nelements) (*ifound)++; /* break statement not encountered */
  } while (++ipass < npass);

  /* Deallocate temporarily used space */
  if (npass > 1) free(tclusterid);

  free(saved);
  free(centroids);
  free(errors);

  return;
}


static void randomassign (int nclusters, int nelements, int* clusterid)
{ int i, j;
int k = 0;
double p;
int n = nelements-nclusters;
/* Draw the number of elements in each cluster from a multinomial
 * distribution, reserving ncluster elements to set independently
 * in order to guarantee that none of the clusters are empty.
 */
for (i = 0; i < nclusters-1; i++)
{ p = 1.0/(nclusters-i);
  j = binomial(n, p);
  n -= j;
  j += k+1; /* Assign at least one element to cluster i */
  for ( ; k < j; k++) clusterid[k] = i;
}
/* Assign the remaining elements to the last cluster */
for ( ; k < nelements; k++) clusterid[k] = i;

/* Create a random permutation of the cluster assignments */
for (i = 0; i < nelements; i++)
{ j = (int) (i + (nelements-i)*uniform());
  k = clusterid[j];
  clusterid[j] = clusterid[i];
  clusterid[i] = k;
}

return;
}


static int binomial(int n, double p)
{ const double q = 1 - p;
  if (n*p < 30.0) /* Algorithm BINV */
  { const double s = p/q;
    const double a = (n+1)*s;
    double r = exp(n*log(q)); /* pow() causes a crash on AIX */
    int x = 0;
    double u = uniform();
    while(1)
    { if (u < r) return x;
      u-=r;
      x++;
      r *= (a/x)-s;
    }
  }
  else /* Algorithm BTPE */
  { /* Step 0 */
    const double fm = n*p + p;
    const int m = (int) fm;
    const double p1 = floor(2.195*sqrt(n*p*q) -4.6*q) + 0.5;
    const double xm = m + 0.5;
    const double xl = xm - p1;
    const double xr = xm + p1;
    const double c = 0.134 + 20.5/(15.3+m);
    const double a = (fm-xl)/(fm-xl*p);
    const double b = (xr-fm)/(xr*q);
    const double lambdal = a*(1.0+0.5*a);
    const double lambdar = b*(1.0+0.5*b);
    const double p2 = p1*(1+2*c);
    const double p3 = p2 + c/lambdal;
    const double p4 = p3 + c/lambdar;
    while (1)
    { /* Step 1 */
      int y;
      int k;
      double u = uniform();
      double v = uniform();
      u *= p4;
      if (u <= p1) return (int)(xm-p1*v+u);
      /* Step 2 */
      if (u > p2)
      { /* Step 3 */
        if (u > p3)
        { /* Step 4 */
          y = (int)(xr-log(v)/lambdar);
          if (y > n) continue;
          /* Go to step 5 */
          v = v*(u-p3)*lambdar;
        }
        else
        { y = (int)(xl+log(v)/lambdal);
          if (y < 0) continue;
          /* Go to step 5 */
          v = v*(u-p2)*lambdal;
        }
      }
      else
      { const double x = xl + (u-p1)/c;
        v = v*c + 1.0 - fabs(m-x+0.5)/p1;
        if (v > 1) continue;
        /* Go to step 5 */
        y = (int)x;
      }
      /* Step 5 */
      /* Step 5.0 */
      k = abs(y-m);
      if (k > 20 && k < 0.5*n*p*q-1.0)
      { /* Step 5.2 */
        double rho = (k/(n*p*q))*((k*(k/3.0 + 0.625) + 0.1666666666666)/(n*p*q)+0.5);
        double t = -k*k/(2*n*p*q);
        double A = log(v);
        if (A < t-rho) return y;
        else if (A > t+rho) continue;
        else
        { /* Step 5.3 */
          double x1 = y+1;
          double f1 = m+1;
          double z = n+1-m;
          double w = n-y+1;
          double x2 = x1*x1;
          double f2 = f1*f1;
          double z2 = z*z;
          double w2 = w*w;
          if (A > xm * log(f1/x1) + (n-m+0.5)*log(z/w)
                + (y-m)*log(w*p/(x1*q))
                + (13860.-(462.-(132.-(99.-140./f2)/f2)/f2)/f2)/f1/166320.
                + (13860.-(462.-(132.-(99.-140./z2)/z2)/z2)/z2)/z/166320.
                + (13860.-(462.-(132.-(99.-140./x2)/x2)/x2)/x2)/x1/166320.
                + (13860.-(462.-(132.-(99.-140./w2)/w2)/w2)/w2)/w/166320.)
             continue;
          return y;
        }
      }
      else
      { /* Step 5.1 */
        int i;
        const double s = p/q;
        const double aa = s*(n+1);
        double f = 1.0;
        for (i = m; i < y; f *= (aa/(++i)-s));
        for (i = y; i < m; f /= (aa/(++i)-s));
        if (v > f) continue;
        return y;
      }
    }
  }
  /* Never get here */
  return -1;
}


static double uniform(void)
{ int z;
  static const int m1 = 2147483563;
  static const int m2 = 2147483399;
  const double scale = 1.0/m1;

  static int s1 = 0;
  static int s2 = 0;

  if (s1==0 || s2==0) /* initialize */
  { unsigned int initseed = (unsigned int) time(0);
    srand(initseed);
    s1 = rand();
    s2 = rand();
  }

  do
  { int k;
    k = s1/53668;
    s1 = 40014*(s1-k*53668)-k*12211;
    if (s1 < 0) s1+=m1;
    k = s2/52774;
    s2 = 40692*(s2-k*52774)-k*3791;
    if(s2 < 0) s2+=m2;
    z = s1-s2;
    if(z < 1) z+=(m1-1);
  } while (z==m1); /* To avoid returning 1.0 */

  return z*scale;
}


void getclustermedoids(int nclusters, int nelements, double** distance,
  int clusterid[], int centroids[], double errors[])

{ int i, j, k;
  for (j = 0; j < nclusters; j++) errors[j] = DBL_MAX;
  for (i = 0; i < nelements; i++)
  { double d = 0.0;
    j = clusterid[i];
    for (k = 0; k < nelements; k++)
    { if (i==k || clusterid[k]!=j) continue;
      d += (i < k ? distance[k][i] : distance[i][k]);
      if (d > errors[j]) break;
    }
    if (d < errors[j])
    { errors[j] = d;
      centroids[j] = i;
    }
  }
}

这些错误是什么意思?我该如何修复它们?

最佳答案

您在声明之前就使用了 kmedoids。这与 C++ 无关,现代 C 编译器也会出现相同的警告。

您要做的就是在使用它之前声明 kmedoids(即您必须在 main 上方的代码中编写函数签名) > -- 或者,您可以通过将完整实现移至 main 之前来定义它。)

现在,该函数在您使用它的第一个点上是未声明的(这意味着编译器不知道它的签名并且无法检查类型。)

另外:阅读本文以了解有关如何声明函数的一些背景知识:http://en.cppreference.com/w/cpp/language/function

关于c++ - 从 C 到 C++ : function was not declared in this scope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25408887/

相关文章:

c++ - 我有一个引用,想调用一个采用 boost::shared_ptr 的函数

c: if elseif else 中的最后一个循环不起作用

c - 使用c编程创建数据库

c - 为什么我的子进程在没有完成任何工作的情况下被父进程等待?

c - 6.5.2.3 结构和 union 成员中 C 中严格别名规则的异常(exception)

android - 错误 : use of undeclared identifier 'PTHREAD_MUTEX_ROBUST' cargo build liblmdb-sys for aarch64-linux-android target

c++ - 在类中使用 vector 的正确语法

c++ - 在运行时为 std::set 定义自定义比较器

c++ - C++ 中带有特殊字符的自定义运算符

c++ - 我可以在字符串中包含 vector 吗?