2013-08-18 6 views
0

Я новичок в C, одна вещь сводит меня с ума, как сделать видимым для всех файлов моего проекта структуру typedef ... Возможно, это ошибка дизайна , не уверена ...Как включить typedef во все мои файлы проекта в C

ступень у меня есть ЬурейаЯ структура, как этого

// File header.h 
typedef struct stu { 
    char name[60]; 
    char id[10]; 
    int age; 
    float puntuation; 
} Student; 

у меня есть несколько структур данных, где я хочу, чтобы использовать этот ЬурейиЙ, у меня есть стек, хеш-таблица и двоичное дерево ... я включаю все в main.c

// File main.c 
#include "header.h" 
#include "hashtable.h" 
#include "stack.h" 
#include "tree.h" 

Мне нужно использовать Student в хэш-таблице и стеке, а также нужно использовать другой тип typedef, определенный в стеке в дереве, но я не могу заставить его работать ...

Компилятор говорит имя типа 'stack_def' неизвестно в tree.h и tree.c, если я исключаю stack.h в main.c и включаю его в tree.h, тогда он говорит то же самое в stack.h для typedef Student.

Может кто-нибудь, пожалуйста, скажите мне, что здесь происходит?

Спасибо.

+2

Компилятор определенно говорить * вы *, что это неправильно, но вы не говорите * нам *. – Jon

+4

Когда вы просите о помощи в любой компьютерной проблеме, вы ** должны ** указать, что происходит не так и что вы хотите. Например, если есть сообщение об ошибке компилятора, покажите его (в этом случае желаемое поведение не является сообщением). Если программа работает, но показывает неправильный вывод, покажите неправильный вывод и покажите, что вы хотите. Когда это возможно, вы должны показать весь исходный код и ввод, необходимый для воспроизведения проблемы. Это может потребовать удаления части программы, чтобы уменьшить ее до [короткого, автономного, компилируемого примера] (http://sscce.org/). –

+0

Все, что я пропустил, теперь #included ... :) – josecash

ответ

1

Мои психические силы говорит мне, что у вас есть циклическая ссылка в ваших заголовков файлов, у вас есть два файла заголовка a.h и b.h, где каждый #include S другого (или, возможно, более длинную цепь, например, a.h включая b.h, который включает в себя c.h, который включает в себя a.h).

Чтобы исправить это, вам нужно удалить ненужные включения - только каждый заголовочный файл включает в себя минимум минимальных других заголовков, которые необходимо правильно компилировать. Если вам нужно всего лишь использовать указатели на определенные типы (без полных определений), вы можете использовать вперед заявление вместо включая типы:

// Forward declaration of `stu' -- we can now use pointers to `stu', but not 
// any of the members of `stu' etc. 
struct stu; 

// Pointer to `stu' -- OK 
struct other_struct 
{ 
    struct stu *a_pointer; 
}; 

// Function parameters and return value of `stu' -- OK 
struct stu function_taking_stu_and_returning_stu(struct stu arg); 

// `stu' instance -- ERROR 
struct another_struct 
{ 
    struct stu not_a_pointer; // ERROR -- `stu' is incomplete 
}; 

После того, как вы удалите круговые зависимости от ваших заголовочных файлов, то должен компилироваться должным образом.

0

В каждом файле, будь то файл заголовка или исходный файл, используйте #include для включения каждого заголовочного файла, который декларирует что-то, что требуется файлу заголовка или исходному файлу. Например, если tree.h использует тип Student, то в tree.h поместить директиву #include, которая включает файл заголовка, который объявляет тип Student. Вы не должны угадывать, что здесь включены заголовки. Это простое правило: если файл использует что-то, объявленное в заголовке, то включите этот заголовок в этот файл.

Очевидно, что если каждый файл содержит заголовки, объявляющие то, что требуется файлу, то ничего не требуется, чтобы файл был необъявлен. Поэтому сообщения об ошибках компилятора должны исчезнуть.

После этого одна проблема, с которой вы можете столкнуться, представляет собой цикл включений, в котором некоторые файлы содержат заголовок, который включает в себя первый файл снова (возможно, косвенно, через цепочку включенных файлов). В простых проектах такой цикл не должен возникать; ни один заголовок не должен зависеть от того, что объявлено другим заголовком, и объявить то, что требуется другому заголовку.Тем не менее, если у вас есть такой цикл, вы можете разбить его, сделав второй включение заголовка имеют никакого эффекта, с помощью так называемых «заголовочные гвардия»:

// Test whether this header has not been included before. 
#if !defined ThisHeaderFileName_h 

// Define a symbol so we know this header has now been included. 
#define ThisHeaderfileName_h 

… // Put body of the header file here. 

// Close the #if. 
#endif