Как объявить структуру в заголовке, который должен использоваться несколькими файлами в c?

Вопрос:Если у меня есть файл source.c со структурой: struct a { int i; struct b { int j; } }; Как эта структура может использоваться в другом файле (т.е. func.c)? Должен ли я создать новый заголовочный файл, объявить структуру там и включить этот заголовок в func.c? Или я должен определить всю структуру в файле заголовка

Вопрос:

Если у меня есть файл source.c со структурой:

struct a { int i; struct b { int j; } };

Как эта структура может использоваться в другом файле (т.е. func.c)?

Должен ли я создать новый заголовочный файл, объявить структуру там и включить этот заголовок в func.c?

Или я должен определить всю структуру в файле заголовка и включить ее как в source.c, так и в func.c? Как можно объявить структуру extern в обоих файлах?

Должен ли я typedef это? Если да, то как?

Ответ №1Содержание

  1. , если эта структура должна использоваться каким-либо другим файлом func.c, как это сделать?
  2. должен ли мы открыть новый файл заголовка и объявить структуру там и включить этот заголовок в func.c?
  3. или мы можем определить общую структуру в заголовочном файле и включить это как в source.c, так и в func.c?
  4. , то как объявить эту структуру как extern в обоих файлах.
  5. , мы должны ввести его тогда, как?
  6. Edit:

, если эта структура должна использоваться каким-либо другим файлом func.c, как это сделать?

Когда тип используется в файле (т.е. файл func.c), он должен быть видимым. Самый худший способ сделать это – скопировать его в каждый исходный файл.

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

должен ли мы открыть новый файл заголовка и объявить структуру там и включить этот заголовок в 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 ;

Будет достаточно, и это уменьшит связь.

или мы можем определить общую структуру в заголовочном файле и включить это как в source.c, так и в func.c?

Это еще один способ, более простой, но менее модульный. Некоторый код, требующий только вашей структуры для работы, все равно должен включать все типы.

В С++ это может привести к интересному усложнению, но это не в тему (нет тега С++), поэтому я не буду подробно останавливаться.

, то как объявить эту структуру как extern в обоих файлах.

Я не вижу смысла, возможно, но Грег Хьюджилл имеет очень хороший ответ в своем посте Как объявить структуру в заголовке, который должен использоваться несколькими файлами в с?.

, мы должны ввести его тогда, как?

  • Если вы используете С++, не делайте этого.
  • Если вы используете C, вы должны.

Причина в том, что управление структурой C может быть болью: вы должны объявить ключевое слово struct везде, где оно используется:

struct MyStruct ; /* Forward declaration */ struct MyStruct { /* etc. */ } ; void doSomething(struct MyStruct * p) /* parameter */ { struct MyStruct a ; /* variable */ /* etc */ }

В то время как typedef позволит вам записать его без ключевого слова struct.

struct MyStructTag ; /* Forward declaration */ typedef struct MyStructTag { /* etc. */ } MyStruct ; void doSomething(MyStruct * p) /* parameter */ { MyStruct a ; /* variable */ /* etc */ }

важно, вы все равно сохраняете имя для структуры. Запись:

typedef struct { /* etc. */ } MyStruct ;

просто создаст анонимную структуру с именем typedef-ed, и вы не сможете ее переадресовать. Итак, держись в следующем формате:

typedef struct MyStructTag { /* etc. */ } MyStruct ;

Таким образом, вы сможете использовать MyStruct везде, где хотите избежать добавления ключевого слова struct, и по-прежнему использовать MyStructTag, когда typedef не будет работать (т.е. форвардное объявление)

Edit:

Исправлено неверное предположение о декларации структуры C99, как справедливо заметил Джонатан Леффлер.

Ответ №2

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

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

extern struct a myAValue;

Затем в одном исходном файле определите действительную переменную:

struct a myAValue;

Если вы забыли сделать это или случайно определить его в двух исходных файлах, компоновщик сообщит вам об этом.

Ответ №3

хиджры:

#ifndef A_H #define A_H struct a { int i; struct b { int j; } }; #endif

там вы идете, теперь вам просто нужно включить a.h в файлы, где вы хотите использовать эту структуру.

Оцените статью
Добавить комментарий