Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка линкера, При компиляции 
:(
    Опции темы
DenisNN
Дата 24.7.2012, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 12.5.2012

Репутация: нет
Всего: нет



Здравствуйте!!! Подскажите пожалуйста почему возникают ошибки линкера?

Код
// main.cpp
#include "parser.h"

int main()
{
 char prog_buff[PROG_SIZE];

  load_program(prog_buff,"E:/projects/vars_test.dci");
 //getch();
 return 0;
}


Код
// parser.h

#pragma once

#include "constants_list.h"
#include "variables_list.h"

const int PROG_SIZE = 10000;

// The DCI command tokens.
enum DCItokensT { UNKNCOM, PRINT, INPUT, IF, THEN, FOR, NEXT, TO,
                 GOTO, GOSUB, RETURN, EOL, FINISHED, END };
// The DCI token types.
enum typesT { UNDEFTOK, OPERATOR, NUMBER, VARIABLE, COMMAND,
              STRING, QUOTE };

/* These are the constants used to call serror() when
   a syntax error occurs.  Add more if you like.
   NOTE: SERROR is a generic error message used when
   nothing else seems appropriate. */
enum errorsT { SERROR, PARENS, NOEXP, DIV_ZERO, EQUAL_EXP,
               NOT_VAR, LAB_TAB_FULL, DUP_LAB, UNDEF_LAB,
               THEN_EXP, TO_EXP, TOO_MNY_FOR, NEXT_WO_FOR,
               TOO_MNY_GOSUB, RET_WO_GOSUB, MISS_QUOTE };

// check for double op
enum double_ops { LE, GE, NE };

// keyword lookup table
/*
struct commands { 
  char command[20]; // string form 
  DCItokensT tok; // internal representation 
} table[] = { // commands must be entered lowercase 
  "print", PRINT, // in this table. 
  "input", INPUT,
  "if", IF,
  "then", THEN,
  "goto", GOTO,
  "for", FOR,
  "next", NEXT,
  "to", TO,
  "gosub", GOSUB,
  "return", RETURN,
  "end", END,
  "", END  // mark end of table 
};*/

char *prog;
typesT tok_type;
DCItokensT tok;
char token[20];

class parser
{
    void serror(errorsT);
    DCItokensT look_up(char*); // convert to internal rep 
    typesT get_token();
    
 public:
    parser();
    ~parser();
    
    bool isdelim(char);
    bool is_sp_tab(char);
};

typesT parser::get_token()
{
 register char *temp;

 tok_type = UNDEFTOK;
 temp = token;
 *temp = '\0';

 if(*prog=='\0') { // end of file 
    *token = '\0';
    tok = FINISHED;
    return(tok_type=OPERATOR);
  }

 if(*prog=='\r') 
  { // crlf 
      ++prog; ++prog;
      return(tok_type = OPERATOR);
  }
  while(is_sp_tab(*prog)) ++prog; // skip over white space

  if(strchr("+-%*/^=()", *prog)){ 
    tok_type = OPERATOR;
    // advance to next char
    *temp++ = *prog++;
  }

  if(strchr("<>", *prog)) { // check for double op
    switch(*prog) {
      case '<':
        if(*(prog+1)=='>') {
          prog++; prog++;
          *temp = NE;
        }
        else if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = LE;
        }
        else {
          prog++;
          *temp = '<';
        }
        temp++;
        *temp = '\0';
        break;
      case '>':
        if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = GE;
        }
        else {
          prog++;
          *temp = '>';
        }
        temp++;
        *temp = '\0';
        break;
    }
    return(tok_type = OPERATOR);
  }
  if(strchr("+-*^/=;(),", *prog)){ // operator
    *temp = *prog;
    prog++; // advance to next position 
    temp++;
    *temp = '\0'; 
    return (tok_type=OPERATOR);
  }
    
  if(*prog=='"') { // quoted string 
    prog++;
    while(*prog!='"'&& *prog!='\r') *temp++ = *prog++;
    if(*prog=='\r') serror(MISS_QUOTE);
    prog++; *temp = '\0';
    return(tok_type=QUOTE);
  }
  
  if(isdigit(*prog)) { // number 
    while(!isdelim(*prog)) *temp++ = *prog++;
    *temp = '\0';
    return(tok_type = NUMBER);
  }

  if(isalpha(*prog)) { // var or command 
    while(!isdelim(*prog)) *temp++ = *prog++;
    tok_type = STRING;
  }
  
  *temp = '\0';

  // see if a string is a command or a variable 
  if(tok_type==STRING) {
    tok = look_up(token); // convert to internal rep 
    if(!tok) tok_type = VARIABLE;
    else tok_type = COMMAND; // is a command 
  }
  return tok_type;
}
/*
  
  

  

  /*
  if(isalpha(*prog) && strstr(prog,"const")) {
    while(*prog != 't') *prog++;*prog++;
    while(is_sp_tab(*prog))*prog++;
    *temp++ = *prog++;
    tok_type = CONSTANT;
  }
   else if(isalpha(*prog)) {
    while(!isdelim(*prog)) *temp++ = *prog++;
    return(tok_type = VARIABLE);
  } 
   else if(isdigit(*prog)) {
    while(!isdelim(*prog)) *temp++ = *prog++;
    return(tok_type = NUMBER);
  }

  *temp = '\0';
}*/

// Return true if c is a delimiter. 
bool parser::isdelim(char c)
{
  if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || c==0) 
    return true;  
  return false; 
}

// Return true if c is space or tab. 
bool parser::is_sp_tab(char c)
{
  if(c==' ' || c=='\t') return true;
  else return false;
}

// Load a program.
bool load_program(char *p, char *fname)
{
  ifstream in(fname, ios::in | ios::binary);
  int i=0;
  prog = p;
  if(!in) {
    cout << "File not found ";
    cout << "-- be sure to specify .BAS extension.\n";
    return false;
  }
  
  i = 0;
  do {
    *p = in.get();
    p++; i++;
  } while(!in.eof() && i<PROG_SIZE);

  // null terminate the program
  if(*(p-2)==0x1a) *(p-2) = '\0'; // discard eof marker
  else *(p-1) = '\0';

  in.close();
  return true;
}
/* Look up a token's internal representation in the
   token table.


DCItokensT look_up(char *s)
{
  register int i;
  char *p;

  // convert to lowercase 
  p = s;
  while(*p){ 
    *p = tolower(*p);
    p++;
  }

  // see if token is in table 
  for(i=0; *table[i].command; i++)
    if(!strcmp(table[i].command, s))
      return table[i].tok;
  return UNKNCOM; // unknown command
}*/
// CONSTANTS
/*
if(isalpha(*prog) && strstr(prog,"const")) {
    while(*prog != 't') *prog++;*prog++;
    while(is_sp_tab(*prog))*prog++;
    *temp++ = *prog++;
    tok_type = CONSTANT;
  }
  */



Код

//variables_list.h

#pragma once

#include "header.h"

const int SIZE_OF_NAME_C = 20;

class vars_list
{
 class node
 {
  
    friend class vars_list;

    char name[SIZE_OF_NAME_C];
    double value;
    node *next;
    node *prev;

 public:
     node(){value = 0;}
     node(double vl):value(vl)
     { }
     ~node(){}    
 };

 public:

    node *head;
    node *tayl;

    vars_list(){}
    ~vars_list(){}

    void create();                // create empty list
    void add_var(char*,double); // add variable
    bool exist(char*);          // if exist

};


///////////////////////////////////////////////////
bool vars_list::exist(char *name)
{

 node *pHead = head;

 while(pHead != tayl)
     if(strstr(name,pHead->name))
         return true;
     else
         pHead = pHead->next;
 return false;
}
///////////////////////////////////////////////////
void vars_list::create()
{
 head = tayl = new node;

 head->next = tayl;
 tayl->next = 0;
 tayl->prev = 0;

}
///////////////////////////////////////////////////
void vars_list::add_var(char *name,double var)
{
 node *pnode = new node(var);
 pnode->next = head;
 pnode->prev = 0;
 head->prev = pnode;
 head = pnode;
 
 int i = 0;
 while(isalpha(*name))
 {
  head->name[i] = *name;
  i++; *name++;
 }
 head->name[i] = '\0';
}



Код

//constants_list.h

#pragma once

#include "header.h"

const int SIZE_OF_NAME_V = 20;

class const_list
{
 class node
 {
  
    friend class const_list;

    char name[SIZE_OF_NAME_V];
    double value;
    node *next;
    node *prev;

 public:
     node(){value = 0;}
     node(double vl):value(vl)
     { }
     ~node(){}    
 };

 public:

    node *head;
    node *tayl;

    const_list(){}
    ~const_list(){}

    void create();                // create empty list
    void add_var(char*,double); // add variable
    bool exist(char*);          // if exist

};


///////////////////////////////////////////////////
bool const_list::exist(char *name)
{

 node *pHead = head;

 while(pHead != tayl)
     if(strstr(name,pHead->name))
         return true;
     else
         pHead = pHead->next;
 return false;
}
///////////////////////////////////////////////////
void const_list::create()
{
 head = tayl = new node;

 head->next = tayl;
 tayl->next = 0;
 tayl->prev = 0;

}
///////////////////////////////////////////////////
void const_list::add_var(char *name,double var)
{
 node *pnode = new node(var);
 pnode->next = head;
 pnode->prev = 0;
 head->prev = pnode;
 head = pnode;
 
 int i = 0;
 while(isalpha(*name))
 {
  head->name[i] = *name;
  i++; *name++;
 }
 head->name[i] = '\0';
}



Код


// header.h

#pragma once

#include <iostream>
#include <fstream>
#include <conio.h>

using namespace std;



 
 

Это сообщение отредактировал(а) bsa - 24.7.2012, 13:20
PM MAIL   Вверх
korian
Дата 24.7.2012, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 2
Всего: 17



а где ошибка линкера и какая?
PM   Вверх
boostcoder
Дата 24.7.2012, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



DenisNN, в следующий раз, в описании темы указывай: требуются телепаты.
я всегда так делаю smile 
PM WWW   Вверх
Gluttton
Дата 24.7.2012, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: нет
Всего: 54



Цитата(korian @  24.7.2012,  12:58 Найти цитируемый пост)
а где ошибка линкера и какая? 

Очевидно что-то типа: "main.cpp: переменная Х дважды объявлена первое объявление здесь: main.cpp."


--------------------
Слава Україні!
PM MAIL   Вверх
bsa
Дата 24.7.2012, 13:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



DenisNN, есть понятия: определение и объявление. Они относятся к функциям, переменным, и даже к структурам/классам. Главное их отличие в том, что определение заставляет компилятор сделать объект, а объявление говорит о том, что объект делается где-то в другом месте. Если ты один и тот же объект сделаешь в двух местах, то линкер тебе выдаст ошибку, так как он не сможет выбрать, какой из них надо использовать.
Ты же определил переменные в хидере, который подключаешь в двух исходниках. В итоге, переменные создаются два раза, и возникает указанная ошибка. Чтобы этого не было, определять переменные следует в исходниках, а в хидерах только объявлять.

Примеры объявлений и определений:
Код
extern int myVar; //объявление
int myVar; //определение

struct MyStruct; //объявление
struct MyStruct //определение
{
  ....
};

int myFunc(void); //объявление
int myFunc(void) //определение/реализация
{
}


Это сообщение отредактировал(а) bsa - 24.7.2012, 13:27
PM   Вверх
Gluttton
Дата 24.7.2012, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: нет
Всего: 54



Цитата(bsa @  24.7.2012,  13:26 Найти цитируемый пост)
то линкер тебе выдаст ошибку, так как он не сможет выбрать, какой из них надо использовать.

Ага! Значит таки я был прав smile !


--------------------
Слава Україні!
PM MAIL   Вверх
DenisNN
Дата 24.7.2012, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 12.5.2012

Репутация: нет
Всего: нет



Спасибо! Проблема была в том,что две функции были объявленны, но не определены!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1119 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.