12.10.2012, 02:50
|
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
в общем, у оптимизатора иногда сносит крышу. всем спасибо за разбор полетов ![Улыбка](images/smilies/icon_smile.gif)
реально я все равно оставил 1-й вариант, к тому же он кардинально короче - всего 12 команд.
|
|
|
|
12.10.2012, 03:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.01.2007
Сообщений: 3,412
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от =GM=
|
Код:
|
void int2hex3(int value, char *str, int digits)
{
char i,hexTable[] = "0123456789ABCDEF";
*str-- =0;
for(i=digits;i;--i,value=value››4) *str-- =hexTable[value & 0x0F];
} |
Сильно не исследовал, ...
Поправьте меня, ...
|
1. hexTable[] действительно, объявлена неудачно. Но глобальные переменные - штука обязывающая, лучше объявить статической.
2. Вычисление конца массива/строки ("int2hex3(0xABCD, &hexvalue[digit], digit);") лучше внести внутрь функции.
3. Оператор простановки терминирующего нуля нужен тогда, когда конец строки имеет переменное положение, а здесь он - лишние накладные расходы.
4. Постдекременты - нехорошая практика.
5. Оператор запятая работает с точностью до наоборот, поэтому цикл будет управляться не значением digits, а нибблами value - если value не превышает 15, цикл не исполнится ни разу, от 16 до 255 - один раз и так далее.
__________________
There's always more than one way to skin a cat.
|
|
|
|
12.10.2012, 04:46
|
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
tempora ‹ох%евший смайлик›
|
|
|
|
12.10.2012, 05:37
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.01.2007
Сообщений: 3,412
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от Hives
|
‹ох%евший смайлик›
|
Да не, ничего особенного. =GM= имел ввиду вот такой принцип, с точностью до шестнадцатиричности и переменного числа знаков.
__________________
There's always more than one way to skin a cat.
Последний раз редактировалось tempora; 12.10.2012 в 05:39.
|
|
|
|
12.10.2012, 05:44
|
|
Гражданин KAZUS.RU
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от tempora
|
1. hexTable[] действительно, объявлена неудачно. Но глобальные переменные - штука обязывающая, лучше объявить статической.
|
static мало - нужно volatile, как минимум...
PS. Локальные переменные - штука не обязывающая?
Сообщение от tempora
|
1. hexTable[] действительно, объявлена неудачно.
4. Постдекременты - нехорошая практика.
|
Чем плоха такая практика? Работать не будет или будет, но медленно?
|
|
|
|
12.10.2012, 05:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.01.2007
Сообщений: 3,412
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от _Артём_
|
нужно volatile, как минимум...
|
Ну, тогда уж и в капслоке.
Локальные - не обязывающая. Пост-инкременты или -декременты такие, как в коде у GM, вводят компилятор в заблуждение, тем и плохи.
__________________
There's always more than one way to skin a cat.
|
|
|
|
12.10.2012, 14:50
|
|
Прописка
Регистрация: 21.09.2009
Сообщений: 218
Сказал спасибо: 1
Сказали Спасибо 29 раз(а) в 27 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от tempora
|
2. Вычисление конца массива/строки ("int2hex3(0xABCD, &hexvalue[digit], digit);") лучше внести внутрь функции.
3. Оператор простановки терминирующего нуля нужен тогда, когда конец строки имеет переменное положение, а здесь он - лишние накладные расходы.
4. Постдекременты - нехорошая практика.
5. Оператор запятая работает с точностью до наоборот, поэтому цикл будет управляться не значением digits, а нибблами value - если value не превышает 15, цикл не исполнится ни разу, от 16 до 255 - один раз и так далее.
|
2. Я думаю компилятору нет разницы, где вычислять адрес записи в строку, внутри функции или в заголовке вызова функции, поскольку адрес вычисляется на этапе компиляции, а не на этапе исполнения. То есть, та же МТС, только вид сбоку.
3. Может и не имеет значения, но digits у автора - это переменная, значит, может принимать спектр значений, скажем от 1 до 8. Если в дальнейшем автор захочет просто распечатать строку, то у него отпечатается не 1-8 символов, а много больше (до 255?), зачем закладывать потенциальную ошибку. В принципе, если завершающий ноль не нужен, то можно вообще отказаться от вызова подпрограммы, а просто вставить такую строчку там, где необходимо:
for(i=digits;i;i--,value››=4) *str-- =hexTable[value & 0x0F];
Да тут вообще можно от i избавиться:
for(;digits;digits--,value››=4) *str-- =hexTable[value & 0x0F]; //в кейле работает
4. Постдекременты и постинкременты - это симметричные операторы, их нужно применять там и так, где это удобно и компактно. Что за запреты такие непонятные?
5. Тут вы немного погорячились. Переменную цикла i никто не отменял, цикл повторяется digits=4 раз. А вот оператор запятая, в данном случае, указывает компилятору проводить вычисления третьего выражения слева-направо, но нам сиё до фени. В приведённом примере видно, что вызов подпрограммы идёт с value=0xABCD=43981 (в десятичке) и, несмотря на ваши предсказания, всё прекрасно работает.
Поскольку в предложенном варианте сдвиг value осуществляется всегда на 4 позиции вправо, то код выполняется быстрее (цикл короче на 2 команды).
К слову сказать, обнаружилось приятное: сдвиг в стмке делается аппаратно на любое количество разрядов. Но если переносить эту программу на другие МК, на чём все немного подвинулись, ну скажем, на 8-битные стм8 или атмеги, то сдвиг 32-х бит value на 28, 24, 20, 16, 12, 8, 4, 0 перерастёт в трагедию о потерянном быстродействии
Последний раз редактировалось =GM=; 12.10.2012 в 15:16.
|
|
|
|
12.10.2012, 15:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Да для быстродействия пиши таблицу байт в Hex (всего то 512 байт при нынешних то флешах) и нет сдвигов никаких и счастьяяяяяяяя ... ))
Только с указателяи играйси ))
|
|
|
|
12.10.2012, 17:14
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.01.2007
Сообщений: 3,412
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от =GM=
|
Я думаю компилятору нет разницы, где вычислять адрес записи
|
Речь не о компиляторе, а о модифицируемости кода. Вычисление конца строки в такой методе - часть алгоритма работы функции, а это значит, что при модификации этого алгоритма придётся отыскивать все вызовы и менять их. И по закону подлости один вызов не будет найден и исправлен, отчего работа программы станет намного интереснее, чем когда всё логично. ![Рот до ушей](images/smilies/icon_doushei.gif)
Не проще ли внести в функцию и менять один раз - в ней?
Сообщение от =GM=
|
но digits у автора - это переменная, значит, может принимать спектр значений, ... отпечатается не 1-8 символов, а много больше (до 255?), зачем закладывать потенциальную ошибку
|
Нет там никакой ошибки - оператор действительно лишний. И количество символов в строке тут совершенно ни при чём. Взгляните на пример.
Сообщение от =GM=
|
Постдекременты и постинкременты - это симметричные операторы
|
Вы не поняли, речь о разнице не между inc-/dec-, а между пре- и пост-, а вот они-то совершенно не симметричны.
Сообщение от =GM=
|
Тут вы немного погорячились.
|
Да, не разглядел одну из ';', отчего думал, что выражение с запятой стоит на месте условия цикла:
__________________
There's always more than one way to skin a cat.
Последний раз редактировалось tempora; 12.10.2012 в 17:17.
|
|
|
|
12.10.2012, 22:04
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Господа, компилятор выполняет только то, что написали. Поэтому
while(str[i++]) и while(str[++i]) переводятся в код именно так как Я ХОЧУ !!!
в первом случае взять str[i], инкрементировать i , затем сравнить взятое с 0 и т.д
во втором случае инкрементировать i , взять str[i] , затем сравнить взятое с 0 и т.д И никаких чудес .
Но !!!! - если я доверяю оптимизатору и включаю его, то тут он и начинает изголяться. И код будет сгенерирован уже в зависимости от качества оптимизатора.
Так что симметричность "пре" и "пост" - это вопрос к оптимизации.
У всех компиляторов отключается оптимизатор !!!
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 13:18.
|
|