2013-03-06 118 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

相關問題