Директивы препроцессоря и заголовочные файлы
- Speccyfan
- Неотъемлемая часть форума
- Сообщения: 540
- Зарегистрирован: 18 дек 2004, 15:15
- Откуда: Polotsk
- Контактная информация:
Директивы препроцессоря и заголовочные файлы
Здравстуйте! Есть вопрос по директивам препроцессора Си и по подключению заголовочных файлов.
На данный момент есть прога, состоящая из:
sf.cpp - основной файл
sf.h - заголовочный к нему
dialog.cpp - еще один файл
dialog.h - к нему заголовочный, он инклудится в sf.cpp
structure.h - файл содержащий структуру с которой работает прога
необходимо вынести пару функций из файла sf.cpp в отдельный файл, делаю так:
создаю файл например quicksort.cpp вставляю туда код трех функций, делаю файл quicksort.h
в нем:
#ifndef quicksortH
#define quicksortH
void quicksort(int f);
int partition(void *arr_el[], int a, int b, int f);
void quicksortr(void *m[],int a,int b, int f);
#endif
По образу и подобию сделаны все заголовочные файлы.
В файлах sf.cpp и sf.h коментирую то, что перенес в другой файл.
в Makefile добавляю quicksort.o, он у меня такой:
CC = g++ -g
all: sf
sf: sf.o dialog.o quicksort.o -lncurses
clean:
rm -f *.o *.a sf
в файл dialog.cpp добавляю #include "quicksort.h"
в quicksort.cpp добавляю несколько инклудов:
#include "sf.h"
#include "quicksort.h"
#include <stdlib>
#include <string>
пытаюсь собрать.
g++ -c -o quicksort.o quicksort.cpp
quicksort.cpp: In function ‘void quicksort(int)’:
quicksort.cpp:17: ошибка: нет декларации ‘Curr’ в этой области видимости
quicksort.cpp: In function ‘int partition(void**, int, int, int)’:
quicksort.cpp:27: ошибка: нет декларации ‘RECORD’ в этой области видимости
quicksort.cpp:27: ошибка: нет декларации ‘t’ в этой области видимости
quicksort.cpp:28: ошибка: нет декларации ‘TRANZ’ в этой области видимости
quicksort.cpp:28: ошибка: нет декларации ‘elj’ в этой области видимости
quicksort.cpp:29: ошибка: нет декларации ‘elb’ в этой области видимости
quicksort.cpp:30: ошибка: нет декларации ‘eli’ в этой области видимости
quicksort.cpp:33: ошибка: expected primary-expression before ‘)’ token
quicksort.cpp:33: ошибка: expected `;' before ‘arr_el’
quicksort.cpp:34: ошибка: expected primary-expression before ‘)’ token
quicksort.cpp:34: ошибка: expected `;' before ‘arr_el’
quicksort.cpp:35: ошибка: expected primary-expression before ‘)’ token
quicksort.cpp:35: ошибка: expected `;' before ‘arr_el’
make: *** [quicksort.o] Ошибка 1
[speccyfan@localhost kurs]$
Ну понятно не видит структуру и соотвественно указатели, добавляю #include "structure.h"
Получается вот что:
[speccyfan@localhost kurs]$ make
g++ -c -o quicksort.o quicksort.cpp
g++ -g sf.o dialog.o quicksort.o /usr/lib/libncurses.so -o sf
quicksort.o:(.bss+0x4): multiple definition of `Curr'
sf.o:(.bss+0x4): first defined here
quicksort.o:(.bss+0x0): multiple definition of `Head'
sf.o:(.bss+0x0): first defined here
quicksort.o:(.bss+0x8): multiple definition of `End'
sf.o:(.bss+0x8): first defined here
collect2: выполнение ld завершилось с кодом возврата 1
make: *** [sf] Ошибка 1
[speccyfan@localhost kurs]$
Дейсвтительно structure.h инклудится и в сам sf.cpp, как бьть ?
конструкции виде #ifndef не помогают
Можно как-нибудь намутить, что б это все собралось ?
На данный момент есть прога, состоящая из:
sf.cpp - основной файл
sf.h - заголовочный к нему
dialog.cpp - еще один файл
dialog.h - к нему заголовочный, он инклудится в sf.cpp
structure.h - файл содержащий структуру с которой работает прога
необходимо вынести пару функций из файла sf.cpp в отдельный файл, делаю так:
создаю файл например quicksort.cpp вставляю туда код трех функций, делаю файл quicksort.h
в нем:
#ifndef quicksortH
#define quicksortH
void quicksort(int f);
int partition(void *arr_el[], int a, int b, int f);
void quicksortr(void *m[],int a,int b, int f);
#endif
По образу и подобию сделаны все заголовочные файлы.
В файлах sf.cpp и sf.h коментирую то, что перенес в другой файл.
в Makefile добавляю quicksort.o, он у меня такой:
CC = g++ -g
all: sf
sf: sf.o dialog.o quicksort.o -lncurses
clean:
rm -f *.o *.a sf
в файл dialog.cpp добавляю #include "quicksort.h"
в quicksort.cpp добавляю несколько инклудов:
#include "sf.h"
#include "quicksort.h"
#include <stdlib>
#include <string>
пытаюсь собрать.
g++ -c -o quicksort.o quicksort.cpp
quicksort.cpp: In function ‘void quicksort(int)’:
quicksort.cpp:17: ошибка: нет декларации ‘Curr’ в этой области видимости
quicksort.cpp: In function ‘int partition(void**, int, int, int)’:
quicksort.cpp:27: ошибка: нет декларации ‘RECORD’ в этой области видимости
quicksort.cpp:27: ошибка: нет декларации ‘t’ в этой области видимости
quicksort.cpp:28: ошибка: нет декларации ‘TRANZ’ в этой области видимости
quicksort.cpp:28: ошибка: нет декларации ‘elj’ в этой области видимости
quicksort.cpp:29: ошибка: нет декларации ‘elb’ в этой области видимости
quicksort.cpp:30: ошибка: нет декларации ‘eli’ в этой области видимости
quicksort.cpp:33: ошибка: expected primary-expression before ‘)’ token
quicksort.cpp:33: ошибка: expected `;' before ‘arr_el’
quicksort.cpp:34: ошибка: expected primary-expression before ‘)’ token
quicksort.cpp:34: ошибка: expected `;' before ‘arr_el’
quicksort.cpp:35: ошибка: expected primary-expression before ‘)’ token
quicksort.cpp:35: ошибка: expected `;' before ‘arr_el’
make: *** [quicksort.o] Ошибка 1
[speccyfan@localhost kurs]$
Ну понятно не видит структуру и соотвественно указатели, добавляю #include "structure.h"
Получается вот что:
[speccyfan@localhost kurs]$ make
g++ -c -o quicksort.o quicksort.cpp
g++ -g sf.o dialog.o quicksort.o /usr/lib/libncurses.so -o sf
quicksort.o:(.bss+0x4): multiple definition of `Curr'
sf.o:(.bss+0x4): first defined here
quicksort.o:(.bss+0x0): multiple definition of `Head'
sf.o:(.bss+0x0): first defined here
quicksort.o:(.bss+0x8): multiple definition of `End'
sf.o:(.bss+0x8): first defined here
collect2: выполнение ld завершилось с кодом возврата 1
make: *** [sf] Ошибка 1
[speccyfan@localhost kurs]$
Дейсвтительно structure.h инклудится и в сам sf.cpp, как бьть ?
конструкции виде #ifndef не помогают
Можно как-нибудь намутить, что б это все собралось ?
Best Regards, Yury Konovalov aka Speccyfan (2:453/53)
Registered Linux User #379588
Registered Linux User #379588
Сперва вопрос не совсем по существу... А зачем делать так?
И накрайняк, есть ведь make "макросы" - $@ для выходного файла для данного make-таргета, и $< для входных файлов...
А где имеет место быть Curr? Это переменная или структура? Если переменная и к тому же инициализированная, то она может быть объявлена только в .срр файле. И если она должна быть видна из коду в другом .срр файле, то надо бы сделать extern. Это уже не имеет отношения к директивам. Если это не инициализированная переменная, то может быть объявлена и в хедере. Короче, не совсем понятно, откуда и куда у Вас этот Curr. Судя по регистру и негласному соглашению (которого придерживаются далеко не все ) TRANZ и RECORD - это должны бы быть не переменные, а типы...
Чтобы не путаться, было бы наверно лучше сделать все включения Ваших заголовков в sf.h, скажем или в какой-нибудь common.h с объявлениями, используемыми разными частями программы и включать его во все .срр .
В общем, чесгря, затрудняюсь дать точный ответ.
опция -l не поддерживается используемой Вами версией g++ и -lncurses не прокатит?g++ -g sf.o dialog.o quicksort.o /usr/lib/libncurses.so -o sf
И накрайняк, есть ведь make "макросы" - $@ для выходного файла для данного make-таргета, и $< для входных файлов...
А где имеет место быть Curr? Это переменная или структура? Если переменная и к тому же инициализированная, то она может быть объявлена только в .срр файле. И если она должна быть видна из коду в другом .срр файле, то надо бы сделать extern. Это уже не имеет отношения к директивам. Если это не инициализированная переменная, то может быть объявлена и в хедере. Короче, не совсем понятно, откуда и куда у Вас этот Curr. Судя по регистру и негласному соглашению (которого придерживаются далеко не все ) TRANZ и RECORD - это должны бы быть не переменные, а типы...
Чтобы не путаться, было бы наверно лучше сделать все включения Ваших заголовков в sf.h, скажем или в какой-нибудь common.h с объявлениями, используемыми разными частями программы и включать его во все .срр .
В общем, чесгря, затрудняюсь дать точный ответ.
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev
- Speccyfan
- Неотъемлемая часть форума
- Сообщения: 540
- Зарегистрирован: 18 дек 2004, 15:15
- Откуда: Polotsk
- Контактная информация:
Будьте внимательней, у меня именно так и сделано, Вы просто немного не туда посмотрелиred f0x писал(а):Сперва вопрос не совсем по существу... А зачем делать так?опция -l не поддерживается используемой Вами версией g++ и -lncurses не прокатит?g++ -g sf.o dialog.o quicksort.o /usr/lib/libncurses.so -o sf
Спасибо учту, я просто только начал изучать Си и еще не писал никогда Make файлов.И накрайняк, есть ведь make "макросы" - $@ для выходного файла для данного make-таргета, и $< для входных файлов...
TRANZ и RECORD это действительно не переменные, а структуры, вот файлА где имеет место быть Curr? Это переменная или структура? Если переменная и к тому же инициализированная, то она может быть объявлена только в .срр файле. И если она должна быть видна из коду в другом .срр файле, то надо бы сделать extern. Это уже не имеет отношения к директивам. Если это не инициализированная переменная, то может быть объявлена и в хедере. Короче, не совсем понятно, откуда и куда у Вас этот Curr. Судя по регистру и негласному соглашению (которого придерживаются далеко не все ) TRANZ и RECORD - это должны бы быть не переменные, а типы...
Чтобы не путаться, было бы наверно лучше сделать все включения Ваших заголовков в sf.h, скажем или в какой-нибудь common.h с объявлениями, используемыми разными частями программы и включать его во все .срр .
В общем, чесгря, затрудняюсь дать точный ответ.
structure.h:
Код: Выделить всё
#ifndef structureH
#define structureH
typedef struct RECORD{
char marka[9];
int type;
float ik;
float uk;
float fw;
}RECORD;
typedef struct _TRANZ {
RECORD * data;
struct _TRANZ *Next,*Prev;
}TRANZ;
TRANZ *Head=NULL, *Curr=NULL, *End=NULL;
#endif
Best Regards, Yury Konovalov aka Speccyfan (2:453/53)
Registered Linux User #379588
Registered Linux User #379588
- Speccyfan
- Неотъемлемая часть форума
- Сообщения: 540
- Зарегистрирован: 18 дек 2004, 15:15
- Откуда: Polotsk
- Контактная информация:
сделал extern TRANZ *Head=NULL, *Curr=NULL, *End=NULL;
вот что пишет:
т.е. особо ничго не изменилось
вот что пишет:
Код: Выделить всё
[speccyfan@localhost kurs]$ make
g++ -c -o sf.o sf.cpp
structure.h:19: предупреждение: ‘extern’ декларация ‘Head’ с инициализацией
structure.h:19: предупреждение: ‘extern’ декларация ‘Curr’ с инициализацией
structure.h:19: предупреждение: ‘extern’ декларация ‘End’ с инициализацией
g++ -c -o dialog.o dialog.cpp
g++ -c -o quicksort.o quicksort.cpp
structure.h:19: предупреждение: ‘extern’ декларация ‘Head’ с инициализацией
structure.h:19: предупреждение: ‘extern’ декларация ‘Curr’ с инициализацией
structure.h:19: предупреждение: ‘extern’ декларация ‘End’ с инициализацией
g++ -g sf.o dialog.o quicksort.o /usr/lib/libncurses.so -o sf
quicksort.o:(.bss+0x4): multiple definition of `Curr'
sf.o:(.bss+0x4): first defined here
quicksort.o:(.bss+0x0): multiple definition of `Head'
sf.o:(.bss+0x0): first defined here
quicksort.o:(.bss+0x8): multiple definition of `End'
sf.o:(.bss+0x8): first defined here
collect2: выполнение ld завершилось с кодом возврата 1
make: *** [sf] Ошибка 1
[speccyfan@localhost kurs]$
Best Regards, Yury Konovalov aka Speccyfan (2:453/53)
Registered Linux User #379588
Registered Linux User #379588
Точно, извиняюсь п/п -l .
А вот остальное... Блин, я не любитель С++, честно говоря , но что-то тут есть, что противоречит здравому смыслу, ИМХО. Может это специфика С++, но в С такое точно невозможно в заголовке:
А вот остальное... Блин, я не любитель С++, честно говоря , но что-то тут есть, что противоречит здравому смыслу, ИМХО. Может это специфика С++, но в С такое точно невозможно в заголовке:
Эти нициализированные переменные должны быть объявлены единожды и в .срр файле, по идее (если с инициализацией). Если Вы их объявляете в .срр файле, то их соотв. надо убрать из заголовка. Далее, при "импорте" переменных в другой .срр файл с пом. extern инициализировать их не надо. Надо сделать просто extern TRANZ *Head, например.TRANZ *Head=NULL, *Curr=NULL, *End=NULL;
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev
Вот Вам пример на С:
файл нумбер 1:
Файл №2, в котором декларируется переменная типа dummy_struct и где она инициализируется:
Основной файл:
Далее, делаем (вручную):
Проверяем работу:
Voila! Что и требовалось... Надеюсь, что чем-то помог.
файл нумбер 1:
Код: Выделить всё
f0x@devel1:~/tmp$ cat ./struct.h
#ifndef _STRUCT_H_
#define _STRUCT_H_
struct dummy_struct {
unsigned field0;
unsigned field1;
};
#endif /* !_STRUCT_H_ */
Код: Выделить всё
f0x@devel1:~/tmp$ cat ./stub.c
#include "struct.h"
struct dummy_struct dummy = { 0, 1 };
Код: Выделить всё
f0x@devel1:~/tmp$ cat ./main.c
#include <stdio>
#include "struct.h"
extern struct dummy_struct dummy;
int main ()
{
printf ("field0=%d, field1=%d\n", dummy.field0, dummy.field1);
return 0;
}
Код: Выделить всё
f0x@devel1:~/tmp$ gcc -o stub.o -c stub.c
In file included from stub.c:1:
struct.h:9:25: warning: no newline at end of file
f0x@devel1:~/tmp$ gcc -o main.o -c main.c
In file included from main.c:2:
struct.h:9:25: warning: no newline at end of file
f0x@devel1:~/tmp$ gcc -o main main.o stub.o
Код: Выделить всё
f0x@devel1:~/tmp$ ./main
field0=0, field1=1
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev