![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Доброго времени суток.
Пишу на C90. Создал три файла: main.c, header.h и library.c. В первом - точка входа, во втором - все необходимые объявления. В третьем - определения функций и static переменных, нужных для их работы. Помимо функций, в library.c определены некоторые перечисления и структуры. Вопрос: как правильно в заголовочных файлах создавать объявления для перечислений и структур, определённых в др. файлах? Спасибо. |
|||
|
||||
feodorv |
|
||||||||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Всё завит от задачи и стиля программирования, которого Вы придерживаетесь ![]() Структуры можно объявлять так (имя структуры - после тела структуры):
Тогда Вы обязаны включить определение этой структуры в ту единицу трансляции, которая использует имя этой структуры. Обычно это никаких трудностей не вызывает: Файл mystru.h
То есть достаточно определение структуры поместить в заголовочный файл, который потом можно включать в любой сишник. Но есть другой вариант (я его сторонник), когда имя структуры следует сразу за ключевым словом struct (перед телом структуры):
Правда тогда везде приходится таскать за собой это самое ключевое слово struct:
Однако если мы имеем дело только с указателями на нашу структуру, то появляется прекрасная возможность объявлять функции или элементы других структур, не раскрывая тела нашей структуры! Например:
Таким образом можно скрыть от пользователя внутреннее устройство самой структуры, но дать ему возможность работать с экземпляром этой структуры опосредованно, через функции. Так часто делают в библиотеках, давая в руки пользователя некий именованный объект, но скрывая его потроха. Правда, и расплачиваться за это приходится дополнительными вызовами функций, которые манипулируют с данными-членами структуры. Очень часто структуре дают оба имени:
Тогда уже существует выбор - в каких-то участках кода использовать struct _my_struct, в каких-то my_struct. Но если происходит наследование одной структуры от другой, то в этом случае знание содержимого структуры обязательно:
Насчёт enum'ов. Не помню, что говорит стандарт на этот случай, но некоторые компиляторы переваривают подобное с перечислением:
Но многие не переваривают... Поэтому лучше всего задавать перечисления явно:
Или вообще не давать перечислению имя, а пользоваться им так, как будто просто задефайнил множество констант:
Перечисления обычно определяются в заголовочных файлах (если они востребованы в разных модулях), но не исключено и определение в одном единственном c-файле, если оно только там и используется... Это сообщение отредактировал(а) feodorv - 9.2.2013, 18:17 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||||||||||||||
|
|||||||||||||||||||||||
Compositum |
|
||||||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Благодарю за расширенный ответ! Интересная информация.
Вы случайно не смешиваете в данных случаях понятие "объявления" с понятием "определения"? Изначально, вопрос моего топика был обусловлен тем, что я ошибочно (как оказалось) считал следующую запись ОПРЕДЕЛЕНИЕМ:
Поэтому я боялся, что разместив эту запись в заголовочном файле, я тем самым растиражирую ОПРЕДЕЛЕНИЕ структуры/перечисления по многим .c-файлам, в связи с чем ожидал возникновения проблем. Но, как оказалось, это на самом деле ОБЪЯВЛЕНИЕ. А раз так, то можно хранить его в заголовке, не опасаясь накладок. На http://stackoverflow.com мне пояснили, что я заблуждался на этот счёт. После этого, порывшись в "Язык программирования C" - нашёл тому подтверждение.
Насколько мне известно, в C нет наследования, поскольку это не объектно ориентированный язык. В приведённом вами коде, я не наблюдаю наследования, но вижу включение экземпляра одной структуры в объявление другой. Или я чего-то не понял? Спасибо. |
||||||
|
|||||||
feodorv |
|
||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Возможно. Но в русском языке употребляется и то и другое слово по отношению к "декларированию" структуры:
Кстати, это тоже "декларирование":
А как по Вашему различаются эти два понятия в данном случае?
Честно говоря, не договорившись о терминах, довольно трудно рассуждать об ошибочности... Пусть будет ОПРЕДЕЛЕНИЕ ![]()
Гм. А это проблема? Вот если у вас где-то в с-файле уже определена структура с этим же именем, то это, да, проблема, компилятор заупрямится и не захочет оттранслировать этот c-файл. Задайтесь вопросом: зачем программисты помещают определения структуры в заголовочных файлах? Что было бы, если бы они не давали определения структур? Каждая единица трансляции в C (на то она и единица) использует свой набор определений типов переменных, не мешая другой единице трансляции. Поэтому если определение структуры, как Вы выражаетесь, "тиражируется" по разным единицам трансляции, то это нормально. Это самая обычная практика (у которой есть свои подводные камни, правда), но так, по-моему, и было изначально задумано. А вот если в одной и той же единице трансляции дано несколько определений структуры с одним и тем же именем, то тут всё зависит от компилятора и определения структур. Некоторые компиляторы сравнивают определения, и если они совпадают, то только выдают предупреждение, что структура определена дважды. Но многие компиляторы не позволяют таких вольностей (недавний пример), что, по-моему, более правильно. Не вижу разницы. Например, декларирование вида
может указываться сколько угодно раз в одной и той же единице трансляции. И как мне теперь называть это декларирование? Так значит, мне теперь нужно везде в этом тексте слово "определение" заменить словом "объявление", "определить" на "объявить" и т.д.? ![]()
Увы, ссылка не о чём. Давайте ссылку на само обсуждение))) Нет, не правильно. В приведённом коде
нет ни одного экземпляра структуры))) Одно сплошное декларирование. По сути, это наследование, но, поскольку си - это не объектно ориентированный язык, то Вы правы, настоящим наследованием не является. По-научному это называется вложенные структуры. Это сообщение отредактировал(а) feodorv - 9.2.2013, 16:20 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||||||||
|
|||||||||||||||||
volatile |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Ребята, вы чего это?
![]()
Это не оба имени, это: 1. Определение структуры 2. Объявление переменной, этого типа Синоним этого выглядит так:
Эта-же ошибка повторяецца и в других местах:
Это не имя структуры, это переменая! |
||||||
|
|||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Не, не, я тоже заметил и поправил:
Добавлено через 1 минуту и 25 секунд В Си такое не прокатывает))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
причем здесь старье не-старье?
Compositum, это не определение структуры. Это объявление переменной, типа безымянной структуры. обычно такая запись делаецца, когда нужна одна такая переменная. К определению типа структуры это никакого отношения не имеет. И имхо должно работать как в старых, так и новых компиляторах С. Потому как это основы языка. В С заголовок такую конструкцию помещать, имхо, можно. В плюсах, кстати нельзя. (впрочем я не глубокий знаток чистого С, пишу на плюсах.) |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |