Правильное подключение #include
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
Собственно столкнулся я с тем, что не могу разобраться в подключении #include. Собственно вопрос: а как их подключать, чтобы было правильно, если в проекте несколько файлов .c и соответствующих им .h ? Например у меня есть два файла .с, функции в которых используют _delay_ms(). Надо ли в каждом из них указать #include "delay.h" и определить F_CPU ? Или это делать в заголовочных файлах .h через #ifndef ? Или достаточно в файле main.c их просто всех перечислить, а компилятор сам разберется, куда и что подсунуть? avr-gss имеется в виду.
- Реклама
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Да.Например у меня есть два файла .с, функции в которых используют _delay_ms(). Надо ли в каждом из них указать #include "delay.h"
Нет. Это делается в настройках проекта или makefile ключом -DF_CPUи определить F_CPU
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
Таким образом получается, что если у меня есть файл lcd.h в котором определена функция lcd_str_out(), и этот файл подключен #include lcd.h в файле main.c и я захочу использовать эту функцию в файле ADC.c, то мне надо будет и в нем прописать #include lcd.h и все include, которые может потребовать эта lcd.h. Правильно? Ну либо перенести использование этой функции из ADC.c в main.c
Добавлено after 1 minute 15 seconds:
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4202518#p4202518"]Нет. Это делается в настройках проекта или makefile ключом -DF_CPU[/uquote]
Atmel Studio не просит в свойствах проекта частоту CPU
Добавлено after 1 minute 15 seconds:
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4202518#p4202518"]Нет. Это делается в настройках проекта или makefile ключом -DF_CPU[/uquote]
Atmel Studio не просит в свойствах проекта частоту CPU
- Сообщения: 12867
- Зарегистрирован: Сб дек 18, 2021 19:25:32
Вам придётся прописать его везде, где используется функция. В этом случае может возникнуть другая ошибка: два и более определений функций. В этом случае как раз используют директивы #ifndef в начале файла .h - тогда при сборке, если уже один раз было собрано, последующие попытки проигнорируются.
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
[uquote="Martian",url="/forum/viewtopic.php?p=4202551#p4202551"]. В этом случае как раз используют директивы #ifndef в начале файла .h - тогда при сборке, если уже один раз было собрано, последующие попытки проигнорируются.[/uquote]
А с переменными тоже так же надо? А то у меня одна переменная должна в двух разных файлах использоваться (результаты из функции в одном файле используются в функции в другом файле. И вот как-то не получается у меня одну переменную к двум файлам привязать. И объявляю вроде как глобальную, т.е. вне функции и volatile использую. Но компилятор не соглашается с моим предложением
Нет, так тоже не получается
А с переменными тоже так же надо? А то у меня одна переменная должна в двух разных файлах использоваться (результаты из функции в одном файле используются в функции в другом файле. И вот как-то не получается у меня одну переменную к двум файлам привязать. И объявляю вроде как глобальную, т.е. вне функции и volatile использую. Но компилятор не соглашается с моим предложением
Нет, так тоже не получается
- Реклама
Land, по F_CPU
Сделайте отдельный заголовочный файл, например, defines.h
В нем определите этот F_CPU и подключайте этот файл во всех ваших файлах, где вы подключаете delay.h
Подключать defines.h нужно перед delay.h
По переменной.
Объявляете эту переменную в одном модуле.
пусть это
unsigned int i;
тогда в нужном вам другом модуле пишете
extern unsigned int i;
и компилятор понимает, что i у нас уже где то есть и не делает еще одну переменную.
Можно все глобальные переменные объявить в main.c, а extern-нотификации описать в том же defines.h и подключать его везде, где надо.
Сделайте отдельный заголовочный файл, например, defines.h
В нем определите этот F_CPU и подключайте этот файл во всех ваших файлах, где вы подключаете delay.h
Подключать defines.h нужно перед delay.h
По переменной.
Объявляете эту переменную в одном модуле.
пусть это
unsigned int i;
тогда в нужном вам другом модуле пишете
extern unsigned int i;
и компилятор понимает, что i у нас уже где то есть и не делает еще одну переменную.
Можно все глобальные переменные объявить в main.c, а extern-нотификации описать в том же defines.h и подключать его везде, где надо.
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Да. Но если у вас и сам код функции тоже в *.h файле - будут проблемы. Тогда либо не использовать эти функции откуда попало, а только из одного *.c файла, либо разделять библиотеку по-человечески на *.c + *.h.Таким образом получается, что если у меня есть файл lcd.h в котором определена функция lcd_str_out(), и этот файл подключен #include lcd.h в файле main.c и я захочу использовать эту функцию в файле ADC.c, то мне надо будет и в нем прописать #include lcd.h и все include, которые может потребовать эта lcd.h. Правильно?
Ну так пропишите -DF_CPU=... во флаги компилятора руками, возможность вписывать свои флаги там естьAtmel Studio не просит в свойствах проекта частоту CPU
Это от многократного включения в ОДИН *.c файл. Если же включаются в разные *.c файлы, это не поможет.В этом случае как раз используют директивы #ifndef в начале файла .h - тогда при сборке, если уже один раз было собрано, последующие попытки проигнорируются.
В *.c файле переменную определяете, а в *.h - объявляете с модификатором extern. Он говорит, что переменная где-то есть, но не тут.А с переменными тоже так же надо? А то у меня одна переменная должна в двух разных файлах использоваться (результаты из функции в одном файле используются в функции в другом файле.
Можно и так, хотя мне привязка к порядку инклюдов не нравится.Сделайте отдельный заголовочный файл, например, defines.h
В нем определите этот F_CPU и подключайте этот файл во всех ваших файлах, где вы подключаете delay.h
Подключать defines.h нужно перед delay.h
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
Большое вам спасибо. Наконец-то пазл сложился, а то кусок оттуда, кусок отсюда, а цельной картины не было. Еще раз большое спасибо за разъяснения )
Да мне тоже. Но в случае delay.h - или прописывать в свойствах проекта, или прописывать в ключах, или следить за порядком инклюдов.COKPOWEHEU писал(а):Можно и так, хотя мне привязка к порядку инклюдов не нравится.
Хотя я этот делей использую редко, в основном у меня суперцикл, привязанный к системному таймеру, и все задержки считаются от системного таймера.
А, и я считаю, что проще прописать или в свойствах проекта, или в инклюднике, нежели бегать по строкам конфига флагов компилятора.
Да, я понимаю, что то, что я пропишу в свойствах проекта - тоже попадет в те же флаги компилятора.
Хотя в свойствах проекта - более наглядно.
Но есть любители собирать проекты руками, писать make в блокнотике, в соседнем блокнотике исходник, компилить из командной строки, прошивать дудкой, делая ей свой батник....
Мне проще всё прописать в свойствах проекта, написать текст в студии, нажать F11 и получить прошивку уже в МК.
встречал не раз подход, когда все подряд h-файлы списком перечисляются в некоем config.h, а потом только этот единственный config.h инклюдится во всех подряд исходниках - типа, коротко и ясно. не могу одобрить такой подход, поскольку главный смысл h-файлов и их включения - хоть как-то ограничить область видимости сущностей, в них описанных. сваливание всего в кучу де-факто аннулирует даже намек на это.
хорошая практика: в каждом с-файле внутри подключаются те и только те h-файлы, которые необходимы для компиляции только этого сишного файла, а в отдельном h-файле с тем же именем, что и сишный, описываются те функции и переменные, которые могут понадобиться другим файлам проекта.
хорошая практика: в каждом с-файле внутри подключаются те и только те h-файлы, которые необходимы для компиляции только этого сишного файла, а в отдельном h-файле с тем же именем, что и сишный, описываются те функции и переменные, которые могут понадобиться другим файлам проекта.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
ARV, правильно. но иногда получается, что для какого то стороннего h-файла нужен некий дефайн. (см. delay.h и F_CPU)
И тут или этот дефайн лепить в каждом с-файле, дабы его увидел delay.h, или делать отдельный заголовочник для общих определений, или писать в свойства проекта / ключи компилятора.
Мне лично удобнее выносить в отдельный общий инклюдник.
Там у меня вагон всего общего живет.
И тут или этот дефайн лепить в каждом с-файле, дабы его увидел delay.h, или делать отдельный заголовочник для общих определений, или писать в свойства проекта / ключи компилятора.
Мне лично удобнее выносить в отдельный общий инклюдник.
Там у меня вагон всего общего живет.
из вашего перечисления только последний вариант правильный - общие для всего проекта константы, дефайны и т.п. следует выносить в опции проекта/компилятора, и никак ниначе.GoldenAndy писал(а):но иногда получается, что для какого то стороннего h-файла нужен некий дефайн. (см. delay.h и F_CPU)
И тут или этот дефайн лепить в каждом с-файле, дабы его увидел delay.h, или делать отдельный заголовочник для общих определений, или писать в свойства проекта / ключи компилятора
то есть это не абсолютное требование, но универсально-правильное.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
ARV, я не любитель руками править всякие ключи компилятора, редактировать make и прочее...
Меня, в принципе, устраивает вынести общий для всех-всех модулей дефайн в конфиг в студии.
Но мне удобнее и проще определить этот дефайн в общем инклюднике.
Там же и другие общие константы/дефайны, typedef-ы и т.д.
Кроме того, когда всё в инклюднике - проще выкладывать исходники. *.c и *.h выложил - и всё. А дальше каждый может попробовать затянуть в свою любимую ide.
Но тут на вкус и цвет - фломастеры разные.
И да, я ж не программист, я только учусь. 33 года уже учусь.
Меня, в принципе, устраивает вынести общий для всех-всех модулей дефайн в конфиг в студии.
Но мне удобнее и проще определить этот дефайн в общем инклюднике.
Там же и другие общие константы/дефайны, typedef-ы и т.д.
Кроме того, когда всё в инклюднике - проще выкладывать исходники. *.c и *.h выложил - и всё. А дальше каждый может попробовать затянуть в свою любимую ide.
Но тут на вкус и цвет - фломастеры разные.
И да, я ж не программист, я только учусь. 33 года уже учусь.
да я не против... я всегда придерживаюсь правила, что веревку достаточной длины, чтобы выстрелить себе в ногу, каждый волен выбирать сам.
только ваш подход чреват тем, что собирая новый проект из "отработанных и гарантированно работающих" старых файлов, вы рискуете в одном из них забыть про какой-то дефайн, и получить чудеса... а так - снова, как я не раз говорил: все полезно, что в рот полезло.
Добавлено after 1 minute 12 seconds:
только ваш подход чреват тем, что собирая новый проект из "отработанных и гарантированно работающих" старых файлов, вы рискуете в одном из них забыть про какой-то дефайн, и получить чудеса... а так - снова, как я не раз говорил: все полезно, что в рот полезло.
Добавлено after 1 minute 12 seconds:
я и сам такой... учусь только дольше - тупой, наверное...GoldenAndy писал(а):я ж не программист, я только учусь. 33 года уже учусь
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться? Делать глобальный .с файл, в который вносить подобные дефайны?
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Потому что #define это просто вставка всего текста из одного файла в другой.
Чего вы хотите добиться этим я вообще не знаю.Делать глобальный .с файл, в который вносить подобные дефайны?
[uquote="Land",url="/forum/viewtopic.php?p=4203121#p4203121"]А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться?[/uquote]
А для этого, Land, в языках программирования существует такое понятие, как область видимости. Покопайте в эту сторону
А для этого, Land, в языках программирования существует такое понятие, как область видимости. Покопайте в эту сторону
Лучше сделать и жалеть, чем жалеть, что не сделал ...
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4203123#p4203123"]Чего вы хотите добиться этим я вообще не знаю.[/uquote]
не прописывать одни и те же дефайны по пять раз в разных файлах. Вроде как очевидно
Добавлено after 30 seconds:
[uquote="JMC.Hard",url="/forum/viewtopic.php?p=4203190#p4203190"][uquote="Land",url="/forum/viewtopic.php?p=4203121#p4203121"]А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться?[/uquote]
А для этого, Land, в языках программирования существует такое понятие, как область видимости. Покопайте в эту сторону
[/uquote]
спасибо.
не прописывать одни и те же дефайны по пять раз в разных файлах. Вроде как очевидно
Добавлено after 30 seconds:
[uquote="JMC.Hard",url="/forum/viewtopic.php?p=4203190#p4203190"][uquote="Land",url="/forum/viewtopic.php?p=4203121#p4203121"]А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться?[/uquote]
А для этого, Land, в языках программирования существует такое понятие, как область видимости. Покопайте в эту сторону
спасибо.
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Что плохого в том, что в каждом файле прописывается именно то, что в нем нужно, а не абы что?не прописывать одни и те же дефайны по пять раз в разных файлах. Вроде как очевидно
- Сообщения: 12867
- Зарегистрирован: Сб дек 18, 2021 19:25:32
Ну, если значение одного и того же дефайна должно быть одним и тем же для всех файлов, где он используется, то как-то странно его прописывать сколько-то раз. В конце концов, если его потом надо изменить, где-то забудется и приведёт к ошибке.





