2013-03-06 45 views
0

我无法编译/链接下面的C代码。链接器抛出类似如下的错误:未定义对'_ *'链接器错误的引用

pso.o:pso.c:(.text+0x41): undefined reference to '_ps' 
... 
pso.o:pso.c:(.text+0x93): more undefined references to '_ps' follow 

这是我第一次写C代码的gcc,所以我不知道该如何解决这个问题。我假设,因为结构PS被定义我的头文件,它不知道与pso.c链接。但是,我确实在该源文件的顶部使用了一个#include“ps.h”语句。

我已经在下面包含了相关的源文件和头文件,以及我正在使用的make文件。我缺少编写可链接C代码的基本概念吗?

谢谢!哦,这是一个粒子群算法,如果你想知道:)

main.c文件:

#define MAIN 
#include<stdio.h> 
#include<stdlib.h> 
#include<time.h> 
#include "ps.h" 

int main(int argc, char *argv[]) 
{ 
    int c; 
    double test; 
    int test_int; 

    srand(time(NULL)); 
    printf("starting pso\n"); 
    pso(); 
    printf("finished pso\n"); 
    return(0); 
} 

有问题的文件,pso.c:

#include<stdio.h> 
#include "ps.h" 

double it(double C[]); 

void pso() 
{ 
    int i; 
    int j; 
    int k; 

    puts("Now in PSO"); 

    /* Initialize PSO controls */ 
    psoi(); 

    /* Initialize particle positions and velocities */ 
    for (i=0;i<MPART;i++){ 
     for(j=1;j<MINDV;j++){ 
      /* positions */ 
      ps.X[i][j]=(-1+2*random())*ps.bup; 

      /* velocities */ 
      ps.V[i][j] = (-1+2*random())*ps.bup/ps.vred; 

      /* Transform */ 
      ps.ut[j] = (ps.X[i][j] - ps.blo)/(ps.bup - ps.blo) * (ps.bnd_hi[i] - ps.bnd_lo[i]) + ps.bnd_lo[i]; 
     } 

     /* Evaluate Finess */ 
     ps.fitness = fit(ps.ut); 

     /* Update particle best position */ 
     ps.pbest[i]=ps.fitness; 

     /* Update swarm best position */ 
     if(ps.pbest[i] < ps.sbest){ 
      for(j=0;j<MINDV;j++){ 
       ps.g[j]=ps.p[i][j]; 
      } 
      ps.sbest = ps.pbest[i]; 
     } 
    } 

    /* Convergenve Loop */ 

    for(k=2;k<ps.maxk;k++){ 
     for(i=1;i<MPART;i++){ 
      for(j=1;j<MINDV;j++){ 
       /* Velocity Update */ 
       ps.rp = random(); 
       ps.rg = random(); 
       ps.rr = random(); 
       ps.chi = 0.7298; 

       ps.V[i][j] = ps.chi * (ps.V[i][j] + ps.phi_p*ps.rp*(ps.p[i][j] - ps.X[i][j]) + ps.phi_g*ps.rg*(ps.g[j] - ps.X[i][j])); 

       /* Position Update */ 
       ps.X[i][j] = ps.X[i][j] + ps.V[i][j]; 
       /* Transform */ 
       ps.ut[j] = (ps.X[i][j]-ps.blo)/(ps.bup-ps.blo)*(ps.bnd_hi[i]-ps.bnd_lo[i])+ps.bnd_lo[i]; 
       } 

      /* Evaluate Fitness */ 
      ps.fitness = fit(ps.ut); 

      /* Update particle best position */ 
      if(ps.fitness < ps.pbest[i]){ 
       for(j=0;j<MINDV;j++){ 
        ps.p[i][j]=ps.X[i][j]; 
       } 
       ps.pbest[i]=ps.fitness; 
      } 

      /* Update swarm best position */ 
      if(ps.pbest[i] < ps.sbest){ 
       for(j=0;j<MINDV;j++){ 
       ps.g[j]=ps.p[i][j]; 
       } 
      ps.sbest = ps.pbest[i]; 
      printf("%f \n",ps.sbest); 
      } 
     } 

     /* Convergence Criteria */ 

    } 
    /* return(0); */ 
} 

头文件定义了数据结构PS(ps.h):

#ifndef _PS_ 
#define _PS_ 
#define MPART 30 
#define MINDV 2 

typedef struct{ 
    /* Design Space */ 
    double X[MPART][MINDV]; 
    double V[MPART][MINDV]; 
    double p[MPART][MINDV]; 
    double u[MINDV]; 
    double ut[MINDV]; 
    double sbest; 
    double sbest_old; 
    double g[MINDV]; 
    double gt[MINDV]; 
    double pbest[MPART]; 
    double pbest_sort[MPART]; 
    double blo; 
    double bup; 
    double fitness; 
    double maxk; 
    double bnd_lo[MINDV]; 
    double bnd_hi[MINDV]; 
    /* PSO behavior */ 
    int psotype; 
    double w; 
    double phi_p; 
    double phi_g; 
    double gam; 
    double chi; 
    double vred; 
    double rp; 
    double rg; 
    double rr; 
}PS; 

/* Dependent Source File Functions */ 
extern void pso(); 
extern double fit(double C[2]); 

#ifndef MAIN 
extern PS ps; 
#endif 
#endif 

最后,我使用的化妆文件:

CC=gcc 
CFLAGS= -I. 
DEPS = ps.h 
OBJ = main.o pso.o psoi.o fit.o 

default: program 

%.o: %.c $(DEPS) 
    $(CC) -c -o [email protected] $< $(CFLAGS) 

program: $(OBJ) 
    gcc -o [email protected] $^ $(CFLAGS) 

回答

2

在 “ps.h”,你也行

extern PS ps; 

- 但这只是声明ps(即断言它某处);它不提供定义(即使其存在于此)。你应该做的是,第一步,更换

#ifndef MAIN 
extern PS ps; 
#endif 

只有

extern PS ps; 

然后,第二步,进入pso.c,并在该文件的顶部水平某处添加

PS ps = {}; 

(或PS ps;extern PS ps = {};)。如果你的C编译器老旧或笨到可以抱怨空括号,改为写PS ps = {0};; {}是一个C++'03主义,我相信它正在被采纳到C'11中,但我不是100%确定的。

简而言之,关于声明的规则是:如果您提供的初始值为=,那么声明必须是一个定义(因为您还可以在这里初始化变量吗?)。否则,如果您使用的存储级别是extern,那么它是而不是的一个定义(因为在助记符上,您表示该变量存在extern-至此文件)。否则,这是一个定义(但在K & R C它是tentative definition,许多编译器将默认将它放在BSS部分,否则提供一个命令行选项来执行此操作)。

+0

感谢您的详细解答!虽然我也必须从'extern PS ps'中删除'extern',但它仍然有效。 – frostbyyte 2013-03-06 20:50:29

2

链接器输出有点混乱,它真的抱怨对象ps丢失的定义。您已宣布它为extern,但从未在任何地方定义它。

+0

你打我...擦... – 2013-03-06 20:19:05

+0

谢谢!我不应该宣布它是一个外部,因为它已经定义了头文件... – frostbyyte 2013-03-06 20:48:39

3

你只声明psextern,但你从来没有真正定义任何地方。写入

PS ps; 

在其中一个C文件中。

+0

感谢您的快速响应和简洁的答案。这是问题,但我也必须从头文件中的“PS ps”中删除“extern”关键字。 – frostbyyte 2013-03-06 20:47:59

相关问题