, Когда тип используется в файле (т.е. func.c файле), это должно быть видимо. Очень худшим способом сделать это является вставка копии, этому в каждом исходном файле был нужен он.
правильный путь помещает его в заголовочный файл, и включайте этот заголовочный файл при необходимости.
Это - решение, мне нравится больше, потому что оно делает код очень модульным. Я кодировал бы Вашу структуру как:
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
я поместил бы функции с помощью этой структуры в том же заголовке (функция, которые являются "семантически" частью ее "интерфейса").
И обычно, я мог назвать файл в честь имени структуры, и использование, которые называют снова для выбора защиты заголовка, определяет.
, Если необходимо объявить функцию с помощью указателя на структуру, Вам не будет нужно полное определение структуры. Простое предописание как:
struct a ;
будет достаточно, и это уменьшает связь.
Это иначе, легче несколько, но менее модульное: Некоторый код, нуждающийся только в Вашей структуре для работы, должен был бы все еще включать все типы.
В C++, это могло привести к интересной сложности, но это вне темы (никакой тег C++), таким образом, я не уточню.
мне не удается видеть точку, возможно, но у Greg Hewgill есть очень хороший ответ в его сообщении , Как объявить структуру в заголовке, который должен использоваться несколькими файлами в c? .
причина, являющаяся этим, управление структуры C может быть болью: необходимо объявить ключевое слово структуры везде оно используется:
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
, В то время как определение типа позволит Вам записать его без ключевого слова структуры.
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
Это важно , Вы все еще сохраняете название структуры. Запись:
typedef struct
{
/* etc. */
} MyStruct ;
просто создаст анонимную структуру с именем редактора определения типа, и Вы не будете в состоянии передать - объявляют его. Поэтому придерживайтесь следующего формата:
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
Таким образом, Вы будете в состоянии использовать MyStruct везде, Вы не хотите добавить ключевое слово структуры, и все еще использовать MyStructTag, когда определение типа не будет работать (т.е. предописание)
Исправленное неправильное предположение об объявлении структуры C99, как законно отмечено Jonathan Leffler .
Craig Barnes напоминает нам в своем комментарии, что Вы не должны разделять названия имени "тега" структуры и его имени "определения типа", как я сделал выше ради ясности.
Действительно, код выше мог быть записан как:
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC, это на самом деле, что C++ делает с его более простым объявлением структуры, негласно, для хранения его совместимым с C:
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
Назад к C, я видел оба использования (отдельные имена и те же имена), и ни один не имеет недостатки, о которых я знаю, так использование того же имени делает чтение более простым, если Вы не используете , C разделяют "пространства имен" для структур и других символов .
Для определения структуры, которое должно использоваться больше чем через один исходный файл, необходимо определенно поместить его в заголовочный файл. Тогда включайте тот заголовочный файл в любой исходный файл, для которого нужна структура.
extern
объявление не используется для определений структуры, но вместо этого используется для объявлений переменной (то есть, некоторое значение данных с типом структуры, который Вы определили). Если Вы хотите использовать ту же переменную больше чем через один исходный файл, объявите его как extern
в заголовочном файле как:
extern struct a myAValue;
Затем в один исходный файл, определяют фактическую переменную:
struct a myAValue;
, Если Вы забываете делать это или случайно определять его в двух исходных файлах, компоновщик сообщит об этом.
a.h:
#ifndef A_H
#define A_H
struct a {
int i;
struct b {
int j;
}
};
#endif
там Вы идете, теперь просто необходимо включать a.h в файлы, где Вы хотите использовать эту структуру.