从C到c++:函数没有在此范围内声明
From C to C++: function was not declared in this scope
我正在从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
在使用函数之前需要声明。
将函数体移到主方法之前,或者使用前向声明:
void kmedoids (int nclusters, int nelements, double** distmatrix, int npass, int clusterid[], double* error, int* ifound);
也要放在用法之前。
相关文章:
- 错误:未在此范围内声明'reverse'
- 错误:"imread"未在此范围内声明
- 未在此范围内声明错误 'xy'
- Socklen_t未在此范围内声明
- 错误:'[' 之前预期的非限定 id 和错误:'users'未在此范围内声明
- "Main"已在当前范围内声明
- c++ 变量在宏的扩展中没有在这个范围内声明
- C++ 在编译过程中 strtok 函数 Eclipse 说没有在范围内声明?
- 'num1'未在此范围内声明
- 如何找到在本地范围内声明的变量的地址?
- NT状态未在此范围内声明
- 变量未在此范围内声明 数组线性搜索
- 包含文件中的 Typdef "未在此范围内声明"
- 'ClassName'和'ClassInstance'未在此范围内声明
- C++ 中的类之间的数据重新循环 - 错误:'<class name>'未在此范围内声明
- 代码作为 C 文件工作,但不作为C++文件,错误:'__builtin_types_compatible_p'未在此范围内声明
- 如何修复错误:"vreinterpretq_u32_f64"未在此范围内声明 - 在Android上使用Eigen构建
- 如何修复C++中的"arrStud未在此范围内声明"错误
- 错误:"SHGetKnownFolderPath"未在此范围内声明
- 错误:'Sprite'未在此范围内声明