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

 
 
7 страниц V  « < 3 4 5 6 7 >  
Reply to this topicStart new topic
> Вопрос к знатокам С.
ARV
сообщение Nov 11 2008, 20:02
Сообщение #61


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



гм... я и не говорил, что пустой if - это норма... я как раз придерживаюсь противоположного мнения... а вот присваивание временной переменной с моей точки зрения - вполне нормальная практика, логичная и не нарушающая никакие стандартны-нормы-правила. volatile тут совсем ни при чем - этот модификатор никто не отменял и его значение (и назначение) не оспаривается.

на счет "специально заведенных переменных"... на сколько я понимаю, при определенном напряжении сил можно очень сложные выражения (например, нечто типа БПФ) уместить в единственном операторе, избежав "лишних" переменных (обычно они называются локальными)... и, хотя с точки зрения результата это будет совершенно верное "выражение", назвать его удобочитаемым будет можно вряд ли. скорее всего и по объему результирующего кода результат не будет отличаться от "развернутого" варианта...

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

можно сколько угодно рассуждать о том, что компилятор "должен сделать", если встретит просто упоминание переменной, но ведь если записать чуть иначе - пропадет сам предмет спора, ибо поведение компилятора станет очевидно на 100%.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2008, 22:04
Сообщение #62


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Если Вам приятно в таком духе - продолжайте, утрируйте, доходите до нелепиц и спорьте с ними - но без меня.
Я вижу разницу между промежуточными переменными для разбивки сложных выражений на более простые и лишними переменными, в которые пишется для того, чтобы никогда из них не читать и этой записью ничего в окружении программы не менять (так как сама эта лишняя переменная - и не SFR и никогда никем не читается).
Если бы эта запись была необходимым или достаточным условием для чтения из переменной в правой части независимо от её volatile-ности, то в этом был бы смысл.
На мой взгляд в такой записи смысла приблизительно столько же, сколько в комментарии
Код
for( i = 0; i < 5; ++i /* инкрементируем счётчик цикла */)
{
}
(хотя для малознакомого с С новичка этот комментарий и повышает читаемость), так как она всего лишь косвенно, через запсиь в другую переменную, говорит "а мы эту переменную прочитали!" для того, кто этого сам не видит. Всего лишь.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
gormih
сообщение Nov 14 2008, 11:31
Сообщение #63


nofb
***

Группа: Свой
Сообщений: 430
Регистрация: 18-05-06
Из: Москва, Зеленоград
Пользователь №: 17 218



a14.gif
Обсуждение напоминает обсуждение кода типа
Код
unsigned char a
if (a == a) {a=a;}

"Индийский код..."
Чем не устраивает вариант с просмотром дизассемблерного варианта полученного кода? Все сразу встанет на свои места - что лучше, а что хуже..


--------------------
Это не то что вы подумали ...

Go to the top of the page
 
+Quote Post
ARV
сообщение Nov 17 2008, 15:59
Сообщение #64


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



хочу для универсализма сделать версию функции printf() для вывода строки на 7-сегментный индикатор, при этом реализация получается примерно такая:
Код
void printf_7led(char *format,  ... ){
   char st[20];
   sprintf(&st, format, ???); // вот тут трабла - обозначена вопросами
   // далее мой код, обрабатывающий st[]
}

трабла такая: как передать "хвост" аргументов, полученных на входе в printf_7led непосредственно в вызываемый sprintf?
P.S. Работаю с WinAVR (GCC)

Сообщение отредактировал ARV - Nov 17 2008, 16:01


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 17 2008, 16:24
Сообщение #65


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Код
void printf_7led(char *format,  ... ){
    va_list args;
    va_start(args, format);
    char st[20];
    vsprintfs(st, format, args);
    va_end(args);
Но это не совсем правильный с точки зрения avr_libc метод. правильно будет примерно так:
Код
int putchar_7led(int symbol, FILE *stream)
{
...
}
FILE Display;

void main()
{
    Display =  FDEV_SETUP_STREAM(putchar_7led, NULL, _FDEV_SETUP_WRITE);


   fprintf(&Display, "%s", "Hello");
   for(;;);
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ARV
сообщение Nov 17 2008, 17:25
Сообщение #66


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



большое спасибо! я вокруг чего-то похожего бродил, но до верного решения так и не дотумкал.
а на счет вывода в поток "дисплея" - мне кажется, это хоть и красивый метод, но для 6-символьного 7-сегментного дисплея наверное слишком избыточный... просто строчку вывел - сразу понятно, что предыдущая затерлась... а при посимвольном выводе надо как-то так же красиво и логично отслеживать момент, когда строка кончилась... не находите?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Dec 11 2008, 08:56
Сообщение #67


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(ARV @ Nov 17 2008, 19:25) *
мне кажется, это хоть и красивый метод, но для 6-символьного 7-сегментного дисплея наверное слишком избыточный... просто строчку вывел - сразу понятно, что предыдущая затерлась... а при посимвольном выводе надо как-то так же красиво и логично отслеживать момент, когда строка кончилась... не находите?
Ну избыточный он не этим - на шести символах просто толком негде разгуляться форматными строками с ширинами полей и т.п.
А что касается "отслеживать момент" - да на раз, було бы желание покуражиться.
Можно заставить по '\n' очищать строку - причём:
- либо сразу по нему, тогда выводить строки вида
"\nHELLO", что будет приводить к очистке и выводу, последующий вывод допишет в конец
- либо по нему запоминать, что строка была завершена и уже последующий вывод очистит и начнёт с начала строки, тогда выводить (&Display, "Err %02X\n", err_code);

Во втором случае в putchar_7led заводится статический флаг, который запоминает прохождение '\n'
Код
int putchar_7led(int symbol, FILE *stream)
{
    static bool newline = true;
    if( symbol == '\n') {
        newline = true;
    } else {
        if( newline ) {
            // прочистить пробелами весь индикатор и поставить указатель символа
            // на начало буфера динамической индикации
        }
        newline = false;
         // вывести символ в текущую позицию
    }
}


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 12 2008, 07:09
Сообщение #68


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(ReAl @ Dec 11 2008, 11:56) *
Ну избыточный он не этим - на шести символах просто толком негде разгуляться форматными строками с ширинами полей и т.п.
А что касается "отслеживать момент" - да на раз, було бы желание покуражиться.
как раз желания куражиться и не было.
я поступил по первому совету - сделал оберточные функции для sprintf с преобразованием нормальных символов в семисегментные и весьма доволен результатом. на верхнем уровне и для семисегментника пишу printf_7led("%.2u", var) - и все выводится smile.gif а когда надо, то и так работает printf_7led("stop"). жаль, не все буквы в семисегментные варианты преобразуются smile.gif особенно кириллица - слишкам многа букафф smile.gif


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 12 2008, 07:15
Сообщение #69


Гуру
******

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



Цитата(ARV @ Dec 12 2008, 10:09) *
...сделал оберточные функции для sprintf

http://electronix.ru/forum/index.php?showtopic=56439&hl=


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 13 2008, 11:46
Сообщение #70


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(zltigo @ Dec 12 2008, 10:15) *
ну да, это и имел ввиду - vsprintf конечно


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 25 2008, 00:06
Сообщение #71


кекс
******

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



Цитата(ARV @ Nov 11 2008, 22:02) *
практика заведения "лишних" переменных лишь для того, чтобы алгоритм вырисовывался четко и ясно с моей точки зрения вполне разумна и оправдана. а компилятор пускай соптимизирует явную избыточность - на то он и компилятор. кстати, весьма оправдан и подход, когда даже небольшие кусочки алгоритма оформляются отдельными функциями - лишь бы наглядность кода была на должном уровне.

Для того чтобы алгоритм вырисовывался "четко и ясно", на мой взгляд больше подходит другая практика.

Во-первых избегать появления дурного кода - т.е. сводить в минимуму потребность в таких вот "var;" и лишних переменных. С какого бодуна драйвер решил вдруг опустошить содержимое буферов? Ведь можно построить драйвер так, что тупое опустошение не понадобится вовсе! Или почему SPSR надо обязательно читать в никуда?
Можно же хотя бы в целях статистики хранить последнее значение SPSR:
Код
ISR()
{
   ...
   spiContext.LastSpsrVal = SPSR;
}

производительности-то оно не сожрет.

во-вторых - применять практику самодокументируемого кода - завести однозначно понятные макросы:
Код
#define access( x )  // обращение к X
#define ignore( x )  // игнорировать x
...


Встретив в коде
Код
access( SPSR );

Даже те "кто в танке" сразу поймут, что делается с SPSR.
А столкнувшись с "финтом" компилятора - достаточно поменять только тело макроса...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2008, 08:21
Сообщение #72


Гуру
******

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



Цитата(defunct @ Dec 25 2008, 03:06) *
С какого бодуна драйвер решил вдруг опустошить содержимое буферов? Ведь можно построить драйвер так, что тупое опустошение не понадобится вовсе!

Научите sad.gif у LPC2000 за тем-же SPI есть FIFO которое
- не отключается
- нет возможности сбросить его
Как сделать запись по SPI так, что-бы когда-нибудь при чтении можно было прочтать SPI, а не содержимое забитого при записи FIFO.
Цитата
Или почему SPSR надо обязательно читать в никуда?
Можно же хотя бы в целях статистики хранить последнее значение SPSR:

Потому, что там содержится "ничто" которое отлично отправляется в "никуда".
Я бы не отказался и от обратной возможности - записи "ничего", а то бывает приходится писать, например,
Код
VICVectAddr = i;            // Dummy write to signal end of interrupt

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

Цитата
spiContext.LastSpsrVal = SPSR;
производительности-то оно не сожрет.

Да? Вместо, например, команды чтения в первый попавшийся расходный регистр будет производится считывание (для load/store через тот-же промежуточный регистр) в структуру находяшуюся в памяти.....
Цитата
Даже те "кто в танке" сразу поймут, что делается с SPSR.

Угу, приходишь в магазин, а там на бутылке с маслом надпись
масло(масло);
Начинаешь думать, а чего это вдруг так написали - может смысл какой есть? Смотришь header спрашиваешь и тебе объясняют,что это масло для танкистов.... smile.gif. В общем-то конечно можно макрос написать, но лишняя сущность.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Dec 25 2008, 11:19
Сообщение #73


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

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



Цитата(zltigo @ Dec 25 2008, 10:21) *
Я бы не отказался и от обратной возможности - записи "ничего", а то бывает приходится писать, например,
Код
VICVectAddr = i;            // Dummy write to signal end of interrupt

А почему не так:
Код
VICVectAddr = 0;
Чтобы избежать лишнего обращения к константе? По-идее будет взята из генератора констант...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2008, 11:42
Сообщение #74


Гуру
******

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



Цитата(HARMHARM @ Dec 25 2008, 14:19) *
Код
VICVectAddr = 0;
Чтобы избежать лишнего обращения к константе? По-идее будет взята из генератора констант...

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 25 2008, 13:29
Сообщение #75


кекс
******

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



Цитата(zltigo @ Dec 25 2008, 10:21) *
Научите sad.gif у LPC2000 за тем-же SPI есть FIFO которое
- не отключается
- нет возможности сбросить его
Как сделать запись по SPI так, что-бы когда-нибудь при чтении можно было прочтать SPI, а не содержимое забитого при записи FIFO.

Думаю, счетчик отправленных байт должен помочь. Драйвер будет вытаскивать из FIFO ровно то количество байт, которое он запихнул при записи.

Цитата
Я бы не отказался и от обратной возможности - записи "ничего", а то бывает приходится писать, например,
Код
VICVectAddr = i;            // Dummy write to signal end of interrupt

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

Можно дать константу (опять же если производительности хватает).
VICVectAddr = 0;
или
VICVectAddr = CurrentVector;
будет чуть-чуть дольше, зато интуитивно понятно, что делается.

Цитата
Да? Вместо, например, команды чтения в первый попавшийся расходный регистр будет производится считывание (для load/store через тот-же промежуточный регистр) в структуру находяшуюся в памяти.....

Да, тут сознательно добавляем запись в память. Медленнее чем в регистр - да, сильно скажется на производительности всей системы - нет! (всего лишь запись одной ячейки на FIFO циклов SPI). Польза от этой записи - когда свалимся в DABT, можно будет снять дамп и посмотреть состояние железа, в т.ч. и значение SPSR (вдруг именно его значение поможет найти причину аборта).

Я говорю не отказаться, а свести к минимуму потребность в пустых чтениях, пустых переменных, и прочем дурном коде, и чтобы не быть пустословным показываю как можно этого добиться. А выбор делать так или нет - как всегда за разработчиком.

Цитата(zltigo @ Dec 25 2008, 10:21) *
Угу, приходишь в магазин, а там на бутылке с маслом надпись
масло(масло);

smile.gif
Ну всяко лучше так, чем взять банку с желтым содержимым без надписи и понять что это совсем не масло, когда содержимое уже плеснули на сковородку. smile.gif

Цитата
В общем-то конечно можно макрос написать, но лишняя сущность.

Дело привычки. Например как Вы поступите если есть некий шаблон колбека:

Код
typedef void (*putmsg_cb)(char *, int, int)


и куча функций подпадающих под этот шаблон, но не использующих все параметры?

Мне удобно поступать так:

Код
void xx_putmsg( char *msg, int size, int priority)
{
    ignore( priority ); // <-- избавились от warning'a и сразу видно, что параметр priority нафиг не нужен
    ...
}
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 20:29
Рейтинг@Mail.ru


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