Технический форум

Технический форум (http://www.tehnari.ru/)
-   C/C++/С# (http://www.tehnari.ru/f42/)
-   -   Подключение модулей (http://www.tehnari.ru/f42/t28660/)

voipp 24.09.2009 23:59

Подключение модулей
 
имеются три сишных модуля и 3 их хидера.
нужно что бы из 1 модуля можно было использовать данные из 2 и3, а из 2 только - 3.по какому принципу их подключать(я имею в виду не синтаксис инклуд)?
Как и где стоит писать директивы препроцессора от двойного копирования, я имею в виду в каких модулях (и)или хидерах.в 1 модуле находится мэйн.

csbwalker 25.09.2009 00:13

Директивы от двойного включения - во всех хидерах, как обычно принято.

А по поводу как подключать - при таком раскладе 2-ой модуль жёстко привязан к 3-му, поэтому логичным было бы (далее для простоты буду описывать в виде номер_модуля.расширение):
в 2.h - include "3.h" - раз уж второй и третий идут исключительно в связке
в 1.h - include "2.h" - на самом деле всё зависит от того, используешь ли ты в интерфейсах первого модуля что-то, определенное во втором и третьем - если да то так, если нет - то можно заинклудить 2.h в файле 1.с
в 3.c - include "3.h"
в 2.c - include "2.h"
в 1.c - include "1.h"

Соответственно в проект (каким бы набором не пользовался) добавляешь три исходника - 1.c,2.c,3.c и всё.

В общем случае - как то так. В некоторых специфических задачах могут быть незначительные вариации - но без них на самом деле как правило спокойно можно обойтись, примерно как без goto))))))))

voipp 25.09.2009 01:12

Тоесть получается что бы была связт во ВСЕХ модулях ДОСТАТОЧНО подключить их таким образом что бы между ними всеми был ПУТЬ? Путь это значит что открывая для некоторого файла a.c файл b.h(b проинклюден в a.h) а в b.h - c.h(который опять же проинклюден в b.h) и так далее то можно добраться до любого .h файла внутренности которого используются в a.c(я имею ввиду конечно же не сам .h файл а соответствующий ему .c файл).Получается как бы дорога между городами - Для города можно достать товары из других городов если между ними есть дорога?

А как насчет подключения библиотек? Если в каком нибудь модуле она используется то где писать ее инклуд и нэймспэйс?

csbwalker 25.09.2009 02:39

Цитата:

Сообщение от voipp (Сообщение 245116)
Тоесть получается что бы была связт во ВСЕХ модулях ДОСТАТОЧНО подключить их таким образом что бы между ними всеми был ПУТЬ? Путь это значит что открывая для некоторого файла a.c файл b.h(b проинклюден в a.h) а в b.h - c.h(который опять же проинклюден в b.h) и так далее то можно добраться до любого .h файла внутренности которого используются в a.c(я имею ввиду конечно же не сам .h файл а соответствующий ему .c файл).Получается как бы дорога между городами - Для города можно достать товары из других городов если между ними есть дорога?

Формально - да.
А фактически - есть некоторое ограничение на максимальную вложенность, поэтому увлекаться проектированием библиотеки или программы в виде таких цепочек зависимостей - не стоит. На практике 5-6 уровней - это нормально.
На самом деле всё намного проще понимается, если учитывать, что include просто вставляет кусок текста программы в место где инклудится. Соответственно когда ты инклудишь файл, в котором подключен другой файл - ты автоматом его тоже подхватываешь.


Цитата:

Сообщение от voipp (Сообщение 245116)
А как насчет подключения библиотек? Если в каком нибудь модуле она используется то где писать ее инклуд и нэймспэйс?

Если она используется только в коде функций/методов - то инклуд в начале c-файла с этими функциями/методами. Если же и в интерфейсе (т.е. в header'ах модуля используется, например, константа или определение класса из этой библиотеки или функция/метод где используется определены прям в .h-файле) - то в хидере к модулю.
А namespace - смотря какой вариант используешь - но либо в начале файла сразу после инклуда, либо, например, в теле определения класса.

На самом деле библиотека или другой модуль - практически нет разницы. Просто библиотека, как правило, уже скомпилирована - а в остальном в использовании это тот же модуль. (Ну, есть правда такая вещь как, например, шаблоны - тут могут быть проблемы с инстанцированием некоторых конкретных классов в случае библиотек - но не думаю что на данном этапе это тебя коснётся).

voipp 25.09.2009 20:29

я подключил в 1.cpp - 1.h и в 1.h - 1.cpp.Но выдается ошибка в загаловке функции в 1.cpp - forward.В этой функции я использую переменную мною определенного типа, описание которого находится в 1.h(там же я написал заголовки всех функций модуля все глобальные переменные и опеределения новых типов).Может все дело в том что в 1.h файле инклуд"1.cpp" стоит почти на самом 1 месте до определений функций и типов?

csbwalker 25.09.2009 20:33

Так...зачем инклуд 1.cpp в 1.h?? Опечатка, на самом деле наоборот?
Вообще предлагаю код "в студию", тогда смогу сказать что не так. Без исходников сложно гадать))

voipp 25.09.2009 20:45

Tree.cpp(не весь) :

#include"Tree.h"
#include<stdlib.h>
#include<iostream>

using namespace std;

void Print_Error(int i){
cout<<"ERROR: ";
switch (i) {
case 0:
cout<<"OK";
break;
case 1:
cout<<"No Memory";
break;
case 5:
cout<<"NoSuchWord";
break;
case 6:
cout<<"Duplicate dict element";
break;
case 7:
cout<<"Bad file format";
break;
case 9:
cout<<"Incorrect type of data elements";
break;
case 129:
cout<<"Incorrect input";
break;
cout<<endl;
};
};


void Left_Rotate(struct RBTree* NIL,struct RBTree* x){
if(x->right!=NIL){
struct RBTree* y;
y=x->right;
x->right=y->left;
if(y->left!=NIL)
y->left->parent=x;
y->parent=x->parent;
if(x->parent!=NIL){
switch (x==x->parent->left){
case true:
x->parent->left=y;
break;
case false:
x->parent->right=y;
break;
};
}
else{
//y->parent=x->parent;
x->parent->left=y;
x->parent->right=y;
NIL->parent=y;
};

y->left=x;
x->parent=y;

};

};

Tree.h :

#pragma once
#ifndef TREE
#define TREE

//#include<string.h>

//#include "Tree.cpp"

// cvet uzla dereva
enum color{RED,BLACK};

// dlina stroki v sluchae tipa STRING
int len=0;

// tipbI kluchey
enum type{SHORT,INT,LONG,STRING};


typedef unsigned int Int;
typedef unsigned long int Long;
typedef unsigned short int Short;

// element slovaria - kluch i znachenia
struct dict{
void* word;
unsigned long int* number;
int size;
};

// struktura dereva
struct RBTree{
enum color col;
struct RBTree* left;
struct RBTree* right;
struct RBTree* parent;
dict* key;
};




// pechatb oshibok
void Print_Error(int i);

// izmenenie znachenii ukazateley sohraniauchee svoistva RB dereva
void Left_Rotate(struct RBTree* NIL,struct RBTree* x);
void Right_Rotate(struct RBTree* NIL,struct RBTree* x);

// pechatb dereva na ekran
void Print_Tree(RBTree* node,int h,RBTree*NIL,type TP);

//void Space(char *str,int* i);

// vosstanovlenie svoistv RB dereva posle vstavki
void Fixup_Insert(RBTree* node,RBTree* NIL);

// vstavka novogo uzla v derevo
void Insert(struct RBTree* NIL,RBTree* node,enum type dict_type);

// vosstanovlenie svoistv RB dereva posle udaleniya
void Fixup_Delete(RBTree* NIL,RBTree* node);

// kopirovanie znachenii odnogo uzla v drugoi
void Copy(RBTree* from,RBTree* to,type dict_type);

// udalenie uzla dereva
bool Delete(RBTree* NIL,RBTree* node,type dict_type);

// poisk uzla v dereve
RBTree* Find(RBTree* NIL,RBTree* top,void* wrd,enum type dict_type);

// polnoe udalenie dereva
void Delete_Tree(RBTree* node,RBTree* NIL);


#endif

Ошибка :
forward declaration в void Left_Rotate(struct RBTree* NIL,struct RBTree* x)

invalid use of: y=x->right;

csbwalker 25.09.2009 21:28

Так...всё очень интересно. Формальных ошибок не нашёл, более того мой компилятор (GCC) съел код за милую душу (при добавлении строчки int main(){;} в конец cpp-файла).
Вообще говоря, forward declaration - это просто предварительное объявление - в данном случае это объявление в h-файле перед непосредственно реализацией в cpp и ошибкой обычно не является - ошибка только если в нескольких местах идёт определение одной и той же функции с разными параметрами (но не перегрузка).
Почему не работает присваивание - из кода тоже непонятно.

Соответственно возможны варианты:
а) Проблема в другой части кода - попробуй собери код из двух обрезанных файлов, что выложил сюда - добавив пустую функцию main. Есть шанс что заработает как и у меня - тогда ошибка в другой части;
б) Проблема в компиляторе? Напиши каким и какой версией пользуешься.



P.S. В след. раз лучше будет выглядеть, если каждый кусок кода (каждый файл) обрамишь в сообщении тегами CODE /CODE
Код:

Будет выглядеть так...и с отступами - читабельнее

voipp 26.09.2009 02:40

main:
Код:

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

int main(void){
int y;
scanf("%d",&y);
return 0;
};

Parsing.h:
Код:


#pragma once
#ifndef PARSING
#define PARSING
#include<iostream>

#include "Tree.h"
//#include "WorkWithDeq.h"

using namespace std;
// .....

#endif

Parsing.cpp:
Код:

#include"Parsing.h"
#include<stdlib.h>
#include<fstream>
#include<iostream>
using namespace std;
//.......

Tree.h:
Код:


#pragma once
#ifndef TREE
#define TREE

//#include<string.h>

//#include "Tree.cpp"

// cvet uzla dereva
enum color{RED,BLACK};

// dlina stroki v sluchae tipa STRING
int len=0;

// tipbI kluchey
enum type{SHORT,INT,LONG,STRING};


typedef unsigned int Int;
typedef unsigned long int Long;
typedef unsigned short int Short;

// element slovaria - kluch i znachenia
struct dict{
        void* word;
        unsigned long int* number;
        int size;
};

// struktura dereva
struct RBTree{
        enum color col;
        struct RBTree* left;
        struct RBTree* right;
        struct RBTree* parent;
        dict* key;
};




// pechatb oshibok
void Print_Error(int i);

// izmenenie znachenii ukazateley sohraniauchee svoistva RB dereva
void Left_Rotate(struct RBTree* NIL,struct RBTree* x);


#endif

Tree.cpp
Код:

#include"Tree.h"
#include<stdlib.h>
#include<iostream>

using namespace std;

void Print_Error(int i){
//.....
};


void Left_Rotate(struct RBTree* NIL,struct RBTree* x){
//.....

};

Ошибка - previous declaration в Tree.h строка с enum type{SHORT,INT,LONG,STRING};

voipp 26.09.2009 02:45

хотя до этого места этого перечисления нигде нет.компилятор g++ непонятно какой версии


Часовой пояс GMT +4, время: 13:39.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.