23.02.2018, 03:18
|
|
Прописка
Регистрация: 25.11.2008
Сообщений: 114
Сказал спасибо: 3
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Препроцессор, линкёр...
Пробую ваять на C (Atmel Studio 7).
С помощью урока (сумбурно там слегка) въехал в такую работающую конструкцию:
Каждый из c "подтягивает" свой h. А main.h "подтягивает" (взаимно) всех остальных h.
Этот набор стрелок может быть ТОЛЬКО таким?
Или горизонтальные можно "поднять" до .h ?
Или "диагональный вариант" - все include в main.c. Допустимо?
Или ещё какие варианты...
Практические уроки с примерами, скриншотами - здорово.
Но хотелось бы понимания. Не только как, но и почему.
Где за всё это почитать?
|
|
|
|
23.02.2018, 03:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: Препроцессор, линкёр...
Линкер фактически просто берет файл, указанный в директиве #include, и подставляет его содержимое аккурат на место этой самой директивы. Благодаря чему в файле, куда подставлено это содержимое, становятся указаны собранные в .h-файлах объявления внешних функций, переменных, типов, определений, для чего обычно* эти файлы и используются.
(*хотя можно извратиться, и, например, где-нить в теле функции вместо ее кода написать "#include "xxx.h", а в файле xxx.h - собственно программные строки функции, линкер подставит содержимое h-файла в указанноге место и всё откомпилируется, как и должно, но востребованность такого решения - под большим вопросом)))
Исходя из этого, если вы включаете другие .h-файлы в main.h - можно во всех .c-файлах указывать #include "main.h" и всё...
Так всегда и делаю. Для проектов не слишком большого масштаба, которыми являются программы для МК, вполне годно.
Ваш же набор стрелок может быть любым, вплоть до того, что в каждом .c-файле включен только "свой" .h-файл, в котором перечислены нужные именно этому .с-файлу внешние переменные, функции, и т.д. из других модулей.
Последний раз редактировалось AR_Favorit; 23.02.2018 в 03:45.
|
|
|
|
23.02.2018, 06:50
|
|
Прописка
Регистрация: 25.11.2008
Сообщений: 114
Сказал спасибо: 3
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: Препроцессор, линкёр...
А на кой вообще нужны эти .h-файлы?
Без них никак?
И ещё. В .h-файлах можно делать определение функций, т.е. располагать собственно саму функцию, её тело?
Или только #include и #define?
|
|
|
|
23.02.2018, 09:59
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,033
Сказал спасибо: 2,559
Сказали Спасибо 11,881 раз(а) в 5,958 сообщении(ях)
|
Re: Препроцессор, линкёр...
Сообщение от DPANYTA
|
А на кой вообще нужны эти .h-файлы?
Без них никак?
|
Можно. А Вам не приходилось разбираться в десятикилометровой портянке, где все в общей куче, одним файлом?
У меня часто в майне вообще линейный (или с небольшим ветвлением) набор кубиков, которые расписаны отдельно, причем, часто тоже с применением кубиков (функций, определенных отдельно). Разбираться очень просто. Сразу видна структура и порядок выполнения. При нормальных именах функций и переменных даже комментарии часто излишни.
Мои "соседи по камере" любят портянки в CV. Я не хочу в них ковыряться.
Думаю, этим ответил и на следующий вопрос.
Сообщение от AR_Favorit
|
Исходя из этого, если вы включаете другие .h-файлы в main.h - можно во всех .c-файлах указывать #include "main.h" и всё...
|
Не, ну не все так просто... Подводных камушков много. Множественные определения и тому прочее. Нужно хорошо думать, ифндеф не всегда спасает. Разное отношение компиляторов к переопределениям: один пропускает - ему все в порядке, другой выдает предупреждение, третий это считает ошибкой. Хуже всего, когда пропускает. Искать такую логическую ошибку весьма трудно.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
23.02.2018, 10:36
|
|
Гражданин KAZUS.RU
Регистрация: 22.07.2007
Адрес: Владивосток
Сообщений: 984
Сказал спасибо: 435
Сказали Спасибо 375 раз(а) в 197 сообщении(ях)
|
Re: Препроцессор, линкёр...
Смысл инклудов мне кажется должен быть в том, что они описывают интерфейс к некоему функционалу, а в сишном файле производится его реализация, конкретное наполнение. Включение заголовка в свой сишный файл гарантирует соответствие интерфейса и реализации. Если у main.c нет интерфейса, то и заголовок не нужен.
Интерфейс это объявления функций и переменных, без тела и начальных значений.
Но механизм этих инклюдов такой примитивный, что никто не застрахован от того, чтобы наворотить огород, т.е. отойти от концепции интерфейс-реализации и делать что в голову взбредет.
Если во вспомогательных файлах используются глобальные переменные программы, то можно объявить их в main.h, но придется страховаться от повторного включения. Но лучше "для чистоты эксперимента" их отдельно определить - типа global.c/global.h. Либо назвать main.h, но никаких include - только объявления глобальных переменных и функций.
Линкер тут ни при чем, т.к. он собирает из объектных двоичных файлов и библиотек готовую программу. С текстом работает компилятор.
|
|
|
|
23.02.2018, 11:05
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,033
Сказал спасибо: 2,559
Сказали Спасибо 11,881 раз(а) в 5,958 сообщении(ях)
|
Re: Препроцессор, линкёр...
Сообщение от ampy
|
Линкер тут ни при чем, т.к. он собирает из объектных двоичных файлов и библиотек готовую программу.
|
Не совсем. Он может отловить ошибку, которую пропустил компилятор. В этом случае поиск ошибки гораздо сложнее именно из-за того, что он собирает из объектных модулей. Сразу скажу, что пример не приведу- бывает это нечасто и в памяти отложился только факт.
Сообщение от ampy
|
Интерфейс это объявления функций и переменных, без тела и начальных значений.
|
Несогласен относительно начальных значений. Начальные значения в заголовочном файле удобней. Типа паблика в плюсах. Но тут тоже надо делать разницу между "текущими" (проще модифицировать) и "типа библиотечными" или стандартными из набора среды разработки (или стандартных библиотек к чипу) - там нехрен ковыряться, можно только посмотреть.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
23.02.2018, 11:37
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: Препроцессор, линкёр...
|
|
|
|
23.02.2018, 11:39
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: Препроцессор, линкёр...
Сообщение от akegor
|
Мои "соседи по камере" любят портянки в CV.
|
Прибейте им табличку на дверь "Зверей не кормить!"(с).
|
|
|
|
23.02.2018, 12:11
|
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,257
Сказал спасибо: 11,169
Сказали Спасибо 3,858 раз(а) в 2,928 сообщении(ях)
|
Re: Препроцессор, линкёр...
Немного неточностей в определениях для начала.
Классически последовательность компиляции состоит из препроцессора и собственно компилятора.
Линкер уже следующий этап с сборкой объектных кодов в исполняемый файл.
Задача препроцессора именно преобразование его директив в код для компилятора.
Эти директивы содержатся как в самом коде (.c файлы), так и в заголовках (.h файлы).
Формально можно и без заголовков обойтись - #include вполне позволяют подключать и сами файлы кода .
DPANYTA По теме стоит просто открыть и почитать первоисточник - книгу Кернигана и Ритчи "Язык программирования C". Там это все разложено по полочкам. Ну и для конкретной среды потом почитать особенности реализации.
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
|
|
|
|
23.02.2018, 12:25
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,033
Сказал спасибо: 2,559
Сказали Спасибо 11,881 раз(а) в 5,958 сообщении(ях)
|
Re: Препроцессор, линкёр...
Сообщение от mike-y-k
|
По теме стоит просто открыть и почитать первоисточник - книгу Кернигана и Ритчи "Язык программирования C". Там это все разложено по полочкам.
|
Не со всем согласен. Там основы. Но. Все течет, все изменяется. Меняются подходы. "С" достаточно гибкий механизм, допустимы большие отклонения и извращения. Тут уж "на вкус и цвет...". Частично отклонения и извращения реализованы в ИДЕ, частично каждым конкретным индивидом. Но нужно читать, чтобы не ходить по известным граблям или чтобы определить, какие грабли наиболее приемлемы.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:22.
|
|