ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Давно терзаюсь вопросами. Имею проект из нескольких c-файлов. Один из них - главный, main.c, в остальных - некие функции (как разбить проект на части - тоже вопрос смутный, как и понятия "драйвер", "core"). Чтобы функции могли вызываться из любого файла, нужно описать их прототипы. Я их описываю в заголовочных h-файлах, соответствующих c-файлам (display.c - display.h). А чтобы не включать всю кучу h-файлов во все c-файлы, собрал их в одну кучу в main.h. Вот его и включаю во все c-файлы (и в main.c тоже). Где-то видел, такие h-файлы называются "helper". Чтобы h-файлы не включались в проект по нескольку раз, заключаю все содержимое в макроопределения: #ifndef DISPLAY_H #define DISPLAY_H ... #endif Также есть отдельные h-файлы, для частных включений. С глобальными переменными дело обстоит чуть сложнее. В своем файле они должны быть определены, а в остальных заданы, как extern. Для этого пользуюсь макроопределениями (создал в main.h): #ifndef VAR_DECLS #define _DECL extern #define _INIT(x) #else #define _DECL #define _INIT(x) = x #endif Только в одном main.c файле задаю определение #define VAR_DECLS, поэтому все переменные будут определены в main.c, независимо от того, в каком h-файле они описаны. Не слишком ли я запутываю свои проекты? Например, гложет мысль, как правильнее - использовать display.h в main.h или в display.c? Поделитесь своими решениями. По каким критериям разбиваете проект на файлы? Где храните переменные? Как передаете глобальные макроопределения (например, #define BUFF_SIZE 4096)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Не слишком ли я запутываю свои проекты? По-моему, слишком. Особенно с переменными. Что мешает сделать в main.c: int global_var = 12345; А в main.h: extern int global_var; ...все переменные будут определены в main.c, независимо от того, в каком h-файле они описаны. Это прямое запутывание: описали в одном месте, а определили в другом, с первым никак очевидно не связанным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
seneka 0 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Давно терзаюсь вопросами. Как передаете глобальные макроопределения (например, #define BUFF_SIZE 4096)? Делаю тоже самое, есть куче локальных файлов *.h, эти локальные файлы прописаны внутри main.h, во всех C файлах прописан только main.h Как там распределяются назначения особо не вникал, но защиту в виде #ifdef поставить в каждом *.h файле надо. Ну и все, нужно прописать буфер, объявляйте его где хотите среди заголовочных файлов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Это прямое запутывание: описали в одном месте, а определили в другом, с первым никак очевидно не связанным. Такого не может быть. Определяется-описывается в одном месте (где угодно, в любом файле, но, очевидно, лучше там, где логичнее) один раз, а попадет во все файлы. Потому что main.h включается во все файлы. Реально определится в main.c, согласно макроопределению _INIT(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Реально определится в main.c, согласно макроопределению _INIT(). Не нужно плодить сущности. Допустим, определению disp_bpp = 16 явно не место в main.c, если есть display.c к которому оно напрямую, а не опосредованно, относится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Не нужно плодить сущности. Допустим, определению disp_bpp = 16 явно не место в main.c, если есть display.c к которому оно напрямую, а не опосредованно, относится. Правильно. Так ведь я и задам определение в display.h, откуда оно попадет в main.h, откуда попадет в main.c как определение, и в display.c как объявление. Так избавляюсь от необходимости определять переменную в display.c и объявлять в остальных файлах (или, хотя бы в display.h). Думаю сделать так же, как вы говорите, в display.c определять переменную, а в display.h объявлять, как extern. Подобно описаниям функций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Тут вот какой вопрос - если бы переменная или макроопределение использовались только в одном файле, то и глобальными их делать незачем. А если не в одном, то в каком...? :rolleyes: Где, как не в main.h? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Давно терзаюсь вопросами. <... А чтобы не включать всю кучу h-файлов во все c-файлы, собрал их в одну кучу в main.h. Вот его и включаю во все c-файлы (и в main.c тоже). Аналогично, только файл называю не main.h а по имени проекта (<project_name>.h). Поделитесь своими решениями. По каким критериям разбиваете проект на файлы? Где храните переменные? С++ избавляет от подобных дилемм, т.к. позволяет практически не иметь глобальных переменных (в крайнем случае используются статические члены-данные), т.е. переменные в глобальном пространстве имён фактически отсутствуют. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Аналогично, только файл называю не main.h а по имени проекта (<project_name>.h). А с-файл как называете - main.cpp или по имени проекта? Тоже колеблюсь туда-сюда. Main найти проще, но смысла меньше. Помню, за имя Top_m в SV модератор по ПЛИСам намекнул, что отгрыз бы своему "падавану" руки. :w00t: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Не слишком ли я запутываю свои проекты? Например, гложет мысль, как правильнее - использовать display.h в main.h или в display.c? Поделитесь своими решениями. По каким критериям разбиваете проект на файлы? Где храните переменные? Как передаете глобальные макроопределения (например, #define BUFF_SIZE 4096)? Нет не запутываете, вы просто копируете в принципе неплохие практики продвигаемые Micrium-ом и другими. Но это еще приемлемо для небольших проектов в пару десятков файлов. А если в проекте счет файлам идет на сотни (а это средненький дивайс с GUI, FS, TCP, RTOS ), то этот подход не работает. Представьте себе main.h с этаким списком в несколько сот заголовочных файлов. Только взглянув на такой поплохеет. Управлять таким и разруливать взаимозависимости просто катастрофа. Проект обязательно надо преобразовать в иерархическую структуру. Поэтому если хотите делать серьезные проекты сразу думайте над иерархией. Иерархия это например: плата (BSP), платформа (PSP), архитектура/драйвера, приложение. Также стоит сразу думать о реюзинге. Отсюда может следовать, что не стоит располагать все глобальные переменные в одном файле. Потом стоит подумать о многозадачности, это может потребовать как можно больше глобальных переменных скомпоновать в структуры чтобы превратить их потом в динамически создаваемые. И т.д. Что касается разбивки на файлы, то могу назвать пару критериев. Как только размер файла подошел к 50 Кб, то его надо как-то разбить, а то время скролинга исходников начинает неявно доминировать в процессе разработки. Если планируется реюзинг каких-то модулей, то эти модули разделяются на файлы зависимые и независимые от платформы. Опять же реюзинг заставляет изобретать уровни абстракции, это тоже порождает файлы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Представьте себе main.h с этаким списком в несколько сот заголовочных файлов. Только взглянув на такой поплохеет. Управлять таким и разруливать взаимозависимости просто катастрофа. Смотрю на примеры с USB, и не въезжаю, что какие файлы делают. Вот их там пара десятков и есть, но не запомнить, где что искать. Много мелких файлов запутывают. С другой стороны, файлы своих исходников есть и больше 150 KB. Да, искать напрягает, Notepad++ пыхтит вместе со мной, зато знаю, что оно где-то там. :rolleyes: Количество файлов как раз под два десятка подбирается. И в них есть и GUI, и RTOS, и DSP. А еще надо и USB, FS... Пока держу все в одном каталоге. Но Keil уже сам создает несколько папок с исходниками в проекте. И еще хочется как-то уровнять файлы по размеру, тоже ищу логику, как делить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Да, искать напрягает, Notepad++ пыхтит вместе со мной, зато знаю, что оно где-то там. :rolleyes: Ну так с этого и надо было начинать. Кто же в Notepad-е делает серьезные проекты. Брать надо SlickEdit или на худой конец Eclipse со специальными add-on-ами. А так конечно упретесь. Ни нормального броузинга исходников, ни рефакторинга. Тут хоть где объявляйте хидеры. Легче не станет. Да еще все в одной директории. Память не резиновая, не надо ее напрасно тренировать поиском по линейным спискам. Используйте более гибкие иерархические структуры и деревья. Память их лучше обрабатывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Ну так с этого и надо было начинать. Кто же в Notepad-е делает серьезные проекты. Брать надо SlickEdit или на худой конец Eclipse со специальными add-on-ами. SlickEdit не пользовался, в Notepad++ найдется все, что нужно, я думаю. И плагины у него тоже есть. Вопрос не в редакторе, а в голове. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба SlickEdit не пользовался, в Notepad++ найдется все, что нужно, я думаю. И плагины у него тоже есть. Вопрос не в редакторе, а в голове. Если бы это было так, то люди до сих пор кодировали в машинных кодах. Вопрос в производительности, которая судя по вашему посту начиная с некого объема кода резко упала. Меня всегда удивляло, что новые языки изобретают не психологи, а гики от программирования. Потом я понял, что все эти новые синтаксисы это только способ размежевания и борьбы программистов между собой. А настоящий прогресс несут редакторы и библиотеки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AnatolyT 0 23 марта, 2014 Опубликовано 23 марта, 2014 · Жалоба Так как до сих пор не делал крупные проекты, типичный проект состоит максимум из 10-15 исходных модулей, стараюсь использовать стандартный подход, к каждому исходнику свой хедер с описанием функций. Все определения типов и свои дефайны определяю в отдельном хедере. Глобальные переменные определяю по мере создания в каждом исходном модуле, потом их легче будет найти по смыслу, использую венгерскую нотацию или скорее похожую на нее. Не определяю крупные массивы для обработки данных, аллокация в хипе в начале каждой обработки, передача через указатель по всей глубине обработки, после обработки освобождаю массив. Стараюсь передавать результат через указатель в формальных параметрах, возврат каждой функции обработки это тип ошибки по всей глубине обработки или 0 если корректное выполнение. Стараюсь не перегружать main.c, только определение прерываний, установка начальных режимов аппаратных модулей и глобальный вызов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться