реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как соблюсти ПРАВИЛА ХОРОШЕГО ТОНА при написании программ на Си?, (Как компоновать проект? Что оставлять в xxx.c, а что в xxx.h ?)
kv_addr
сообщение May 4 2009, 18:14
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Написал было объемистое предисловие, но Фаерфокс глюкнул и оно исчезло, поэтому обойдусь без него.

Перешел с ассемблера на Си, создал ряд проектов, работающих, но так и не получил четкого представления о том, как нужно оформлять программу на Си по ПРАВИЛАМ. Может сказалась былая практика программирования на Фортране и Паскале. Наибольшее непонимание у меня вызывает то, что нужно оставлять в xxx.c, а что выносить в xxx.h. Виной тому - ужасная чересполосица в куче разных сторонних проектов, которые довелось разбирать в процессе освоения Си. В одних проектах водораздел один, в других - совсем иной. И даже в атмеловских аппноутах - тоже полный разнобой.

Пользуюсь IAR EWAVR-ом.

Вот пара примеров написания программ, с которыми встречался:
Имеются: основной модуль - xxx.c, хедер к нему - xxx.h, пара модулей - yyy.c, zzz.c и хедеры к ним yyy.h, zzz.h.

Первый вариант организации проекта. В проект подключен основной модуль xxx.c, в котором в самом начале подключен при помощи директив #include необходимый набор стандартных библиотек, хедер xxx.h, а также два дополнительных модуля yyy.c и zzz.c. В самих модулях yyy.c и zzz.c при помощи этих директив подключены yyy.h и zzz.h соответственно. В основном модуле располагается главная программа и набор функций, относящихся непосредственно к ней. В хедере располагаются глобальные определения, описания глобальных переменных и констант, а также прототипы функций основного модуля. В дополнительных модулях располагаются функции модулей, а в хедерах дополнительных модулей располагаются определения, переменные, константы и прототипы, касающиеся этих модулей.


Во втором варианте организации проекта дополнительные модули включены в проект подобно основному. В основном же модуле при помощи #include подключены yyy.h и zzz.h. Также они подключены с помощью этой директивы и в yyy.c и zzz.c соответственно.

Оба проекта полностью рабочие, потому как в конечном счете все полностью завязано и в первом и во втором случае.

Встречался также с вариантами написания программ, где, например, описания переменных вынесены в ***.c вместо ***.h.

Имею два конкретных вопроса:

1. КАК нужно подключать в проект модули и хедеры согласно ПРАВИЛ ХОРОШЕГО ТОНА написания программ на языке Си?
2. ЧТО нужно согласно тех же ПРАВИЛ выносить в ***.h, а что оставлять в ***.c?

Четкого, внятного, однозначного ответа я так и не нашел. Хотелось бы узнать мнение уважаемого сообщества.

PS: Конечно, можно компоновать как попало, имея в результате полноценный рабочий код, но вопрос в том, как общепринято ПРАВИЛЬНО это выполнять?
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 4 2009, 19:22
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



C Си нет ничего проще. В хидерах только прототипы функций, переменных, структур, константы, макросы. Крайне редко ввиде исключения могут быть, например, функции форсируемые в качестве инлайновых. Никакие *.c никогда через include не включаются - на то есть линкер.
Стандартным примером разумной организации являются системные хидеры.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение May 4 2009, 19:23
Сообщение #3


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(kv_addr @ May 4 2009, 21:14) *
Первый вариант организации проекта. В проект подключен основной модуль xxx.c, в котором в самом начале подключен при помощи директив #include необходимый набор стандартных библиотек, хедер xxx.h, а также два дополнительных модуля yyy.c и zzz.c.

Обычно С файлы через #include не подключают. Объясню далее. Видимо, это ваш второй вариант.
Цитата
Во втором варианте организации проекта дополнительные модули включены в проект подобно основному. В основном же модуле при помощи #include подключены yyy.h и zzz.h. Также они подключены с помощью этой директивы и в yyy.c и zzz.c соответственно.
...
1. КАК нужно подключать в проект модули и хедеры согласно ПРАВИЛ ХОРОШЕГО ТОНА написания программ на языке Си?
2. ЧТО нужно согласно тех же ПРАВИЛ выносить в ***.h, а что оставлять в ***.c?

Все моё ИМХО.
Модули нужно подключать, подключив хидеры xxx.h; линкеру дать инструкции подключить объектные файлы полученные из сырцов xxx.c.

Header - это в первую очередь описания интерфейсов. В понятие интерфеса входят методы, глобальные переменные, константы (для С++, в С с константами хуже, обычно там define). Почему в хидерах не пишут код? Дело в том, что в случае изменения кода в .с файле пересобирается этот файл. А в случае изменения в хидере пересобираются еще и все модули, которые включают этот хидер (зависимые модули). То есть в хидере - то, что видно снаружи. В сырцах - все остальное.
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 4 2009, 19:45
Сообщение #4


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Никакие *.c никогда через include не включаются - на то есть линкер.


Мне кажется, слишком категорично. Иногда делаю отдельный .c-инклуд для уменьшения видимых размеров исходника с сохранением одной единицы компиляции. Иногда выношу константы в отдельный .c-файл, когда эти константы static и генерируются отдельным софтом в пребилде.

Конечно, можно обойтись без этого, но мне иногда так удобнее. Собственно, это больше издержки отсутствия пространств имен в
plain c.


Вспомнилось... Третий турбопаскаль под CP/M умел собирать код под всю память только при инклуде исходников с диска и компиляции на диск. Иначе не лезло smile.gif Но это так, ностальжи...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 4 2009, 19:55
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Rst7 @ May 4 2009, 22:45) *
Мне кажется, слишком категорично.

Исключения только подтверждают правило smile.gif. Я тоже исключение приводил. Ну а "единицу компиляции" уже можно многие компиляторы просить обеспечить вне зависимости от количества составляющих ее файлов.
Цитата
Иногда выношу константы в отдельный .c-файл, когда эти константы static и генерируются отдельным софтом в пребилде.

А в этом приеме где противоречие с невключением файлов с исходниками по include?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 4 2009, 20:14
Сообщение #6


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Исключения только подтверждают правило


Ну Вы же грамотный человек, зачем употребляете нелогичную фразу wink.gif Исключения только опровергают правило (или ограничивают область применимости, это если с точки зрения физики) smile.gif

Да и многофайловая компиляция - недавнее приобретение wink.gif

А второй пример - это я к тому, что подключается на этапе препроцессора. Хоть и .с. Повторюсь - в большинстве случаев это издержки отсутствия namespace.

Гм, мне кажется, или движок форума шибко вумный, приклеивает точку к предыдущему слову?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 4 2009, 20:18
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Rst7 @ May 4 2009, 23:14) *
Ну Вы же грамотный человек, зачем употребляете нелогичную фразу wink.gif

Это все основоположники римского права - "Exceptio probat regulam in casibus non exceptis" http://en.wikipedia.org/wiki/Exception_that_proves_the_rule


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 4 2009, 20:46
Сообщение #8


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
это все основоположники римского права


Я в курсе smile.gif

Кстати, а как Вам параллель этого утверждения (точнее его оригинальной формы про ограничение) с теоремой Геделя о неполноте? Можем пойти в оффтоп обсудить, там есть кому подхватить, страниц на 20-30 smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
kv_addr
сообщение May 4 2009, 22:46
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



TNX. Где-то так и предполагал, что второй вариант будет более правильным и логичным.

Следующий вопрос. Каков общепринятый порядок расположения компонентов хедера? Это на мой взгляд далеко не праздный вопрос. Хотелось бы впредь выработать четкие правила создания логично скомпонованных удобочитаемых и удоборазбираемых программ. Для своего потребления я могу программу наклепать как угодно, все равно она будет работать согласно установленного алгоритма, но для других она будет выглядеть диковато и не удобоваримо.

Я не совсем новичок в программировании, пописывал программы еще когда вычислительные машины были большими и очень большими. wink.gif Но в основном я - схемотехник, поэтому это было как бы приложением к основной работе. Когда появились "писюки", писать программы на них как-то не приходилось. К микроконтроллерам приступил наперевес с ассемблером. Но когда задачи усложнились, писать на ассемблере стало чрезмерно времязатратным. Поэтому, преодолев некоторые фобии, решил освоиться с Си. Конечно, embedded C весьма специфичен, но вроде уже как освоился и программу "чувствую". Но, понимая, что это немаловажно, также решил упорядочить стиль создания программ, дабы писАть wink.gif не только под себя. Вот, собственно говоря, это и есть основной причиной моих вопросов.

Кстати, хотя по Си перечитал литературы достаточно, но так и не нашел четких ЛАКОНИЧНО изложенных правил. Может кто подскажет такой источник. Предпочтительно - русскоязычный. Это не значит, что по-английски не читаю, но предпочитаю родной язык, как более удобный в любом случае.
Go to the top of the page
 
+Quote Post
Slash
сообщение May 5 2009, 06:31
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 202
Регистрация: 10-04-05
Из: Санкт-Петербург
Пользователь №: 4 011



Кое какие правила есть в книге "Искусство программирования на С. Фундаментальные алгоритмы, структуры данных и примеры приложений" Ричард Хэзфилд, Лоуренс Кирби.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 5 2009, 07:00
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Rst7 @ May 4 2009, 23:46) *
Можем пойти в оффтоп обсудить, там есть кому подхватить, страниц на 20-30 smile.gif

Нет sad.gif там любая тема всегда к одному и тому-же сводится sad.gif. Я тут недавно эксперимента ради объединил темы про "опель" и "гомосексуализм" в одну и НИЧЕГО НЕ ИЗМЕНИЛОСЬ smile.gif.
Ну а с подтверждением правил на самом деле все логично - если признается существование единого общего правила, то тогда все отклонения от него являются ИСКЛЮЧЕНИЯМИ из правила, что самим своим названием "исключение", заметьте "исключение", а не "правило номер 2" подтверждает наличие "правила".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 5 2009, 07:01
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(kv_addr @ May 5 2009, 01:46) *
 Конечно, embedded C весьма специфичен

Как можно больше скрывайте особенности реализации. Иерархия абстракций тсз. Чем больше кода отойдет в процессоронезависимую часть - тем лучше.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 5 2009, 07:03
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Slash @ May 5 2009, 09:31) *
Кое какие...

Уже ожнажды писал на форуме - единственная книга с "правилами" хорошо совпадающими с собственным опятом и шишками была Керниган и Пайк "Практика программирования".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 5 2009, 07:35
Сообщение #14


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Ещё одно из немаловажных правил хорошего тона, к осознанию которого я шёл пару лет, это автодокументация кода.
Причём систематизированная, единообразная по шаблону.
Постепенно прихожу к комментариям в стиле doxy, в дальнейшем планирую требовать этого же и от коллег.

Очень упрощает жизнь не только другим, но и себе, когда спустя несколько лет смотришь в код и соображаешь - ё-моё, чтож я сделал-то?!


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Legotron
сообщение May 5 2009, 07:36
Сообщение #15


инопланетянин
***

Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832



Цитата(kv_addr @ May 5 2009, 02:46) *
Следующий вопрос. Каков общепринятый порядок расположения компонентов хедера? Это на мой взгляд далеко не праздный вопрос. Хотелось бы впредь выработать четкие правила создания логично скомпонованных удобочитаемых и удоборазбираемых программ. Для своего потребления я могу программу наклепать как угодно, все равно она будет работать согласно установленного алгоритма, но для других она будет выглядеть диковато и не удобоваримо.
о говоря, это и есть основной причиной моих вопросов.

Я где-то такую последовательность видел.. но точно не вспомню где..
Я обычно делаю так:
Код
     #ifndef _XXX_H_
       #define _XXX_H_
    
     1. макросы, константы
     2. определения типов структур, объединений
     3. экспортируемые переменные
     4. экспортируемые функции
    
     #endif


Также я во всех проектах создаю файл includes.h, который включен во все *.с, больше никаких include в с-файлах..
А includes.h выглядит примерно так:
Код
   #ifndef _INCLUDES_H_
     #define _INCLUDES_H_
  
   /*
   ********************************************************************************
   *                                Project Includes
   ********************************************************************************
   */
  
   #include "main.h"
  
   #include "Timer0.h"
   #include "Timer1.h"
   #include "io_ports.h"
   #include "sync.h"
  
   #include <stdlib.h>      
   #include <string.h>
   #include <util/atomic.h>
   #include <util/delay.h>
   #include <avr/power.h>
   #include <avr/sfr_defs.h>
   #include <compat/deprecated.h>
   #include <avr/eeprom.h>
  
   #include "avrport.h"
   #include "config.h"
   #include "hwclock.h"          
   #include "keys.h"
   #include "led.h"    
   #include "nnspi.h"      
   #include "ntrxdil.h"    
   #include "ntrxiqpar.h"
   #include "ntrxranging.h"
   #include "ntrxtypes.h"
   #include "ntrxutil.h"  
   #include "OffstMapInit.h"  
   #include "usart.h"
   #include "rtc.h"
  
   #include "usart_my.h"
   #include "usart_protocol.h"
   #include "io_ports.h"
   #include "led.h"
   #include "ascold.h"
   #include "ext_flash.h"
   #include "soft_spi.h"
   #include "i2cmaster.h"
   #include "temp.h"
   #include "adc.h"
   #include "soft_reset.h"
   #include "eeprom_map.h"
  
   #include "gui_fonts_defs.h"
   #include "fonts.h"
   #include "gui.h"
   #include "lcd.h"
   #include "simple_font_digit.h"
  
  
   #endif

Цитата(kv_addr @ May 5 2009, 02:46) *
Кстати, хотя по Си перечитал литературы достаточно, но так и не нашел четких ЛАКОНИЧНО изложенных правил. Может кто подскажет такой источник. Предпочтительно - русскоязычный. Это не значит, что по-английски не читаю, но предпочитаю родной язык, как более удобный в любом случае.

Макконелл, Совершенный Код.. достаточно интересная книга, много всяческих небольших ньюансов, про которые не пишут в классических учебниках
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 13:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.015 секунд с 7
ELECTRONIX ©2004-2016