|
|
  |
Стиль программирования на Си, описание функции |
|
|
|
Mar 31 2008, 10:23
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Добрый день! Столкнулся со следующей проблемой. нашол код как сделать восемь таймеров написанный Alechin Jan. Первое что кидается в глаза та это синтаксис мне непонятный. Вот к примеру прототип функции остановки тай мера: Код void Stop_Timer(IN IDX timer); ну и сама функция: Код /*--------------------------------------------------------------------------------------------*/ /* Процедура остановки таймера. */ /* Принимает: номер таймера (0 - 7). */ /* Возвращает: ничего не возвращает. */ /*--------------------------------------------------------------------------------------------*/ __monitor void Stop_Timer(IN IDX timer) { Timer[timer].Timer_Ena = TIMER_DIS; return; } Непонятно что такое IDX? Ну IN понятно, направление, очень удобно. IDX по ходу здесь беззнаковый чар. Ну и соответственно вопрос: Этот синтаксис возможен через какоето макроопределение? Может кто знает, подскажите, уверен это интерессно не только мне. Вот ещё пример Код void Start_Timer(IN IDX timer, IN WORD interval, IN pTIMER_FUNC pFunc = NULL, IN bool cycle = TIMER_ONCE); Спасибо.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Mar 31 2008, 10:36
|

Частый гость
 
Группа: Новичок
Сообщений: 140
Регистрация: 31-01-07
Из: Челябинск
Пользователь №: 24 896

|
Цитата(sKWO @ Mar 31 2008, 16:23)  Этот синтаксис возможен через какоето макроопределение? Да, typedef, или через структуру.
Сообщение отредактировал Axxel - Mar 31 2008, 10:40
--------------------
Если боишься - не говори. если сказал - не бойся. ©
|
|
|
|
|
Mar 31 2008, 10:59
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата Этот синтаксис возможен через какоето макроопределение? да, и через макроопределение: Код #define CHAR char и через typedef Код typedef char CHAR; Но думаю что конкретно в вашем примере IDX задумывался быть перечислимым типом, объявленным через enum Код typedef enum { TIMER1 = 0, TIMER2, TIMER3, .... , TIMER_COUNT } IDX;
|
|
|
|
|
Mar 31 2008, 11:56
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(defunct @ Mar 31 2008, 14:59)  да, и через макроопределение: Код #define CHAR char и через typedef Код typedef char CHAR; Но думаю что конкретно в вашем примере IDX задумывался быть перечислимым типом, объявленным через enum Код typedef enum { TIMER1 = 0, TIMER2, TIMER3, .... , TIMER_COUNT } IDX; Ага, спасибо. Чёта мучают сомнения нащёт квалификатора перечисления Но тогда непонятно это (Его же стиль) Код OUT bool Wait_LCD_Ready(IN IDX c) Да, тогда ещё вопрос : Если возможности препроцессора ограничены, то лучше использовать typedef используя возможности компилятора? И в каких случаях предпочтительнее #define? Если кому не тяжело , приведите конкретный пример чтобы компилятор проглотил! Спасибо! Цитата(Axxel @ Mar 31 2008, 14:36)  Да, typedef, или через структуру. ПОКАЖИЦитата(aaarrr @ Mar 31 2008, 14:40)  Стиль жуткий, не надо так делать. Возможно, но мне просто интерессно. Просто в голове не укладывается как ?!
Сообщение отредактировал sKWO - Mar 31 2008, 11:58
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Mar 31 2008, 12:16
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(sKWO @ Mar 31 2008, 18:56)  Да, тогда ещё вопрос : Если возможности препроцессора ограничены, то лучше использовать typedef используя возможности компилятора? И в каких случаях предпочтительнее #define? Во всех случаях, где можно выбирать, предпочтительнее использовать средства компилятора, а не препроцессора. Использование препроцессора нужно свести к минимуму, в идеале исключить вообще. Но на практике это не удается сделать, поэтому приходится жить с ним. По большому счету препроцессор имеет смысл использовать только для реализации условной компиляции да простеньких макроподстановок типа вставки платформенно-зависимых квалификаторов.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 31 2008, 12:48
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Во всех случаях, где можно выбирать, предпочтительнее использовать средства компилятора, а не препроцессора. Использование препроцессора нужно свести к минимуму, в идеале исключить вообще. Просветите, плз, откуда такая категоричная постановка? Цитата По большому счету препроцессор имеет смысл использовать только для реализации условной компиляции да простеньких макроподстановок типа вставки платформенно-зависимых квалификаторов. Почему-то приходится применять гораздо шире. Где не вижу тонкой грани?
--------------------
aka Vit
|
|
|
|
|
Mar 31 2008, 14:08
|
Частый гость
 
Группа: Свой
Сообщений: 158
Регистрация: 27-06-05
Из: Химки, Моск.обл.
Пользователь №: 6 334

|
Так как кусок кода мой - скажу как это описано у меня (то бишь в оригинале):
// Тип переменной, занимающей 1 байт (0..255). typedef unsigned char BYTE; #define MAX_BYTE ((BYTE)-1)
// Тип переменной-указателя на переменную, занимающую байт. typedef BYTE * pBYTE;
//-------------------------------------------------------------------------------------------- // Тип индексной переменной (0..255); typedef unsigned char IDX; #define BAD_IDX ((IDX)-1)
//-------------------------------------------------------------------------------------------- // Тип переменной, занимающей 2 байта (0..65536). typedef unsigned short WORD; #define MAX_WORD ((WORD)-1)
// Макрокоманда получения значения младшего байта слова. #define LO_BYTE(word) (BYTE)(word)
// Макрокоманда получения значения старшего байта слова. #define HI_BYTE(word) (BYTE)((WORD)(word) >> 8)
// Макрокоманда формирования значения типа WORD из двух значений типа BYTE. #define MAKE_WORD(lo, hi) (WORD)(((BYTE)(lo)) | ((WORD)(hi) << 8))
// Тип переменной-указателя на переменную, занимающую 2 байта. typedef WORD * pWORD;
//-------------------------------------------------------------------------------------------- // Тип переменной, занимающей 4 байта (0..4 294 967 296). typedef unsigned long int DWORD;
// Тип переменной-указателя на переменную, занимающую 4 байта. typedef DWORD * pDWORD;
// Макрокоманда получения значения младшего слова двойного слова. #define LO_WORD(dword) (WORD)(dword)
// Макрокоманда получения значения старшего слова двойного слова. #define HI_WORD(dword) (WORD)((DWORD)(dword) >> 16)
// Макрокоманда формирования значения типа DWORD из двух значений типа WORD. #define MAKE_DWORD(lo, hi) (DWORD)(((WORD)(lo)) | ((DWORD)(hi) << 16))
//-------------------------------------------------------------------------------------------- // Тип переменной, занимающей 8 байт. typedef unsigned long long QWORD;
// Макрокоманда получения значения младшего двойного слова четверного слова. #define LO_DWORD(qword) (DWORD)(qword)
// Макрокоманда получения значения старшего двойного слова четверного слова. #define HI_DWORD(qword) (DWORD)((QWORD)(qword) >> 32)
// Макрокоманда формирования значения типа QWORD из двух значений типа DWORD. #define MAKE_QWORD(lo, hi) (QWORD)(((DWORD)(lo)) | ((QWORD)(hi) << 32))
// Тип переменной-указателя на переменную, занимающую 8 байт. typedef QWORD * pQWORD;
//-------------------------------------------------------------------------------------------- // Тип переменной-счетчика секунд. typedef DWORD SECONDS_CNTR;
|
|
|
|
|
Mar 31 2008, 14:13
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Извиняюсь, что вклиниваюсь. Цитата(sensor_ua @ Mar 31 2008, 18:48)  Просветите, плз, откуда такая категоричная постановка? Для переносимости кода. Потому, что компиляторы пишут обычно как можно ближе к стандарту языка программирования. А препроцессоры по большей части не стандартизованы (исключая может быть лишь #define и #include). И то, что работает на одном, не обязательно поймет препроцессор другого компилятора. Кроме того, препроцессор не проверяет типы данных и соответственно, оперируя его командами, можно допустить такие ошибки, которые потом "вылавливать" дольше и сложнее.
|
|
|
|
|
Mar 31 2008, 14:17
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(sKWO @ Mar 31 2008, 13:56)  Чёта мучают сомнения нащёт квалификатора перечисления Но тогда непонятно это (Его же стиль) Код OUT bool Wait_LCD_Ready(IN IDX c) Правильно мучают. Стиль действительно странный, не упирайтесь в него. Попробуйте переписать. Для арифметики гораздо удобнее объявить типы с короткими именами, и которые будут говорить сами за себя: Код typedef unsigned char U8; typedef unsigned short U16; typedef unsigned long U32; typedef unsigned long long U64;
typedef signed char S8; typedef signed short S16; typedef signed long S32;
typedef volatile unsigned char V8; typedef volatile unsigned short V16; typedef volatile unsigned long V32;
|
|
|
|
|
Mar 31 2008, 14:39
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Для переносимости кода. ... IMNHO, совсем неубедительно. Именно перепроцессором разруливаю проекты на AVR (IAR/GCC) и LPC (RVDMK/IAR), имеющие общий API. Полезные макросы пишутся, естественно, так, чтобы портировалось корректно, очень многие функции параметризуются макроопределениями по шаблонам. На работе препроцессора завязано очень много, при этом несовместимости как-то не наблюдается
--------------------
aka Vit
|
|
|
|
|
Mar 31 2008, 14:51
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(sensor_ua @ Mar 31 2008, 20:39)  IMNHO, совсем неубедительно. Именно перепроцессором разруливаю проекты на AVR (IAR/GCC) и LPC (RVDMK/IAR), имеющие общий API. Полезные макросы пишутся, естественно, так, чтобы портировалось корректно, очень многие функции параметризуются макроопределениями по шаблонам. На работе препроцессора завязано очень много, при этом несовместимости как-то не наблюдается  Уже были и неоднократно пояснения почему typedef предпочтительнее #define. Пользуйтесь поиском. Вот, например, одна из недавних веток обсуждения http://electronix.ru/forum/index.php?showt...&hl=typedef
|
|
|
|
|
Mar 31 2008, 15:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Уже были и неоднократно пояснения почему typedef предпочтительнее #define Спасибо, но я неплохо понимаю, что такое typedef, ну и когда может быть полезно применить #define. Если рассматривать только typedef и #define, то в основном соглашусь с Вами. Только какое это имеет отношение к переносимости кода? Цитата Объясняется все просто: код, активно использующий препроцессор сложно читать, сопровождать и отлавливать ошибки Если использование макроопределений, скажем, явно избыточно, не используются правила образования имен, то соглашусь. Также замечу, что без достойного инструмента, позволяющего "ходить" по коду не только по функциям и переменным, но и по макроопределениям, отлаживаться также может быть затруднительно. Но, если нотации определены и их придерживаются, а инструмент заточен, то всё путём.
--------------------
aka Vit
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|