Вопрос про #define для отладки и вывод имени переменной
- Войдите на сайт для отправки комментариев
Пт, 17/01/2020 - 04:41
Нашел такие вот полезные сокращения для дебага.
#define PRINT(x) Serial.print(x)
Но чаще надо вывести не просто значение, а еще и имя.
Serial.print("Name = "); Serial.println(Name);
Можно эти две команды как-то задефайнить похожим образом в одну? Name же одинаково.
#define PRINT(X) Serial.print("X = "); Serial.println(X);
??
Пользовать:
А у меня вопрос: do { } while() какую-то специфическую задачу решают в этом выражении?
А у меня вопрос: do { } while() какую-то специфическую задачу решают в этом выражении?
Простите, если Вы решили пошутить и вызвать ответную шутку, ... я только что встал, плохо соображаю и шутить не могу, могу только начать занудно объяснять для чего оно там. Или Вам это и нужно? Вы, правда не знаете?
Кстати, обратите внимание (!) я исправил там опечатку - убрал ";" в конце макроса - она там категорически не нужна, "пальцы сами как-то вставили".
никогда не понимал всех этих ваших макросов, и вот опять...
Нет, не шучу. Я просто оставил блок печати в { } и не заметил никаких проблем со встраиванием в код. Поэтому и уточняю - в каких случаях я получу геморрой.
Нет, не шучу. Я просто оставил блок печати в { } и не заметил никаких проблем со встраиванием в код. Поэтому и уточняю - в каких случаях я получу геморрой.
Согласен, фигурных скобочек должно быть достаточно.
Я просто оставил блок печати в { } и не заметил никаких проблем со встраиванием в код.
фигурных скобочек должно быть достаточно.
Ну, в простейших случаях - да, достаточно, но макрос же пишется для общего применения, поэтому должен позволять использовать себя везде, где допустима функция, без ограничений и со стандартным для функции синтаксисом.
Пара скобок Вас подведёт в тех местах, где после закрывающей скобки нельзя ставить точку с запятой. Если поставите - ошибка компиляции, а не поставите - использование "на вид функции" без точки с запятой в конце будет выглядеть странно.
Например, с моим макросом вполне нормально компилируется вот такая конструкция.
А если в макросе оставить только скобки (убрать do-while), то попробуйте её скомпилировать - фигвам.
Можно, конечно, написать вот так:
но выглядит это неестественно, согласитесь.
Поэтому, решение с do-while стандартное и универсальное для функциональных макросов, его пишут автоматом, не задумываясь.
Спасибо, теперь буду знать.
Кстати, Sakolua,
возьмите вот эту библиотеку и поставьте её ко всем библиотекам. Сможете печатать просто функцией printf со всеми её наворотами, также сможете использовать потоки, типа ' Serial << "a=" << a << "\n"; '. Ну, и макрос, который я для Вас в первом посте написал, там тоже есть - printVar называется.
а float в уно никак не поддержать?
В смысле? Serial.print (и соответственно Serial <<) вполне его поддерживает. Или Вы о чём?
float pi = 3.1459;
printf ("i = %d, pi = %f\n", i, pi);
"pi = ?"
Опция компилятора есть спицальная. Для таких случаев
а float в уно никак не поддержать?
Просто - нет. А сложно - оно Вам точно надо? :-)
а почему бы нет? что в этом плохого? полно параметров в дробных, почти любой датчик
полно параметров в дробных, почти любой датчик
ошибаетесь, большинство (просто практически все) датчики работают в целых числах. А во флоат переводят только перед выводом - исключительно для тупых человеков.
очень полезная информация, какая мне разница в чем они там работают, большинство вообще только сопротивление да напряжение меряют, так может мне температуру в омах считать? )))
а почему бы нет? что в этом плохого? полно параметров в дробных, почти любой датчик
сейчас еще раз за сегодня объяснят, что работать надо с целыми
Вполне вероятно, что для китайских даччиков так будет правильнее
а почему бы нет? что в этом плохого? полно параметров в дробных, почти любой датчик
сейчас еще раз за сегодня объяснят, что работать надо с целыми
мы тут про вывод говорили
Как бы это не было смешно, но BME680, например, концентрацию VOC в омах выдаёт.
очень полезная информация, какая мне разница в чем они там работают, большинство вообще только сопротивление да напряжение меряют, так может мне температуру в омах считать? )))
Считайте хоть в литрах, это Ваше дело, но посмотрите как работают с любым аналоговым датчиком на примере простейшего измерения напряжения на пине:
1. читаем напряжение с АЦП в целых "попугаях" - получаем целое число от 1 до 4 десятичных цифр.
2. переводим целые попугаи в число с плавающей точкой
3. для печати переводим число с плавающей точкой в целое и указание где поставить десятичную запятую
4. печатаем это целое, впихнув запятую куда надо.
Вы не видите здесь лишних шагов?
Мне нужно вывести значения переменных, проверить условие и выполнить какие-то действия
Вывод
В выражении, когда определение используется как операнд, "стандартное" не собирается, а "нестандартное" работает
Вполне возможно.
Мне правда непонятен приведённый пример (
if
(printIt2(a), printIt2(b), printIt2(c), c > a)
) - зачем так навёрнуто и какой в этом смысл? Более осмысленного примера нет?Смысла столько же как и использование запятых в операторе for т.е. выполни одно, другое, третье и т.д.
Стивен Прата в учебнике говорит
Применение операции запятой не ограничивается только циклами for, однако,
именно здесь она чаще всего используется. Эта операция имеет еще два характерных
свойства.
Во-первых, она гарантирует, что выражения , которые она отделяет одно от
другого, вычисляются в порядке слева направо.
Во-вторых, значение всего выражения, содержащего операцию запятой, является
значением выражения вправой части. Результат оператора.
х = (у = З, (z = ++у + 2 ) + 5);
Выполняется последовательность действий, и только последнее используется для присваивания.
В операторе if точно так же, выполняется последовательно до последнего разделителя, после него - выражение для проверки.
Спасибо, буду знать :-)))
а float в уно никак не поддержать?
Просто - нет. А сложно - оно Вам точно надо? :-)
ну простое serial.print печатает pi
я даже не предположу где вообще такое нахрен нужно
(if (printIt2(a), printIt2(b), printIt2(c), c > a))
кроме как чемпионата по браинфак)
"заметили мой пост"
так вот и не понятно - почему тут работает, а тут уже нет?
почему тут работает, а тут уже нет?
а в жизни всегда так - на жигули хватает, а на майбах уже нет... И почемутак??
философ флудерный
Мне нужно вывести значения переменных, проверить условие и выполнить какие-то действия
Вывод
В выражении, когда определение используется как операнд, "стандартное" не собирается, а "нестандартное" работает
С одними фигурными как то не красиво. Я тоже раньше писал через do while (0), но затем обленился и пишу через запятую в обычных скобках.)
Что то специалисты все молчат... А хотелось бы критики.)
Зачем?
Ну как зачем? Должны же быть подводные камни, которые мне совсем не видны?)
Green,
ладно, только букв будем много. Мой талант - один у папы с мамой, нет у него сестёр :-(
Понимаете, не бывает «лучших для любой ситуации» решений. В данном топике я «на автомате» использовал do-while (безо всякой мысли вбросить тему для дискуссии, поверьте). Этот подход для данного применения вполне хорош. Меня спросили, а чем может (в какой-то ситуации!!!) подвести просто пара фигурных скобок. Я ответил примером. Поверьте, если бы меня спросили «а чем может (в какой-то другой ситуации!!!) подвести do-while», я бы тоже ответил, не сомневайтесь. Не бывает решений на все случаи жизни. Это как спросить «чем вкуснее закусывать – салом или шоколадом?». Пока мы не знаем, что именно нужно закусывать, водку или коньяк – ответа быть не может.
Если Вас интересует конкретно пара круглых скобок, ну давайте на неё посмотрим и поищем ей «место под солнцем», где она заведомо лучше того же do-while, а где хуже.
Первое, что бросается в глаза – выражение в круглых скобках может иметь значение (в каких-то случаях), а do-while – никогда, его нельзя ничему присваивать. Отсюда вывод: если наш «функциональный макрос» должен возвращать значение, которое можно чему-то присвоить, то про do-while нужно просто забыть, т.к. его нельзя ничему присвоить, а скобки могут и подойти!
А как в случае, если не нужно возвращать значение? Если бы делаем «void макрос»? Что использовать? do-while или скобки? Всё равно? Ан нет, в этом случае do-while предпочтительнее! Сейчас покажу на примере.
Допустим, нам нужно атомарно брать значение волатильного флага в локальную переменную, сбрасывая при этом значение волатильного флага (довольно типичная задача). Я написал два макроса – один с do-while, а другой со скобками (не смотрите на варварскую работу с SREG – это искусственный пример для демонстрации проблемы).
Запускаем и, независимо от того какой макрос используется (закомментирована строка №4 или нет), получаем один и тот же результат
Т.е. flag получил значение, которое было у myFlag до вызова макроса, а myFlag сбросился. Всё здорово! Но это только пока мы делаем всё правильно.
А вот теперь, представьте, что другой человек модифицирует этот код (или тот же человек, но через год, или там с бодуна) и по имени макроса getFlag этот программист предположит (ошибочно), что макрос не просто меняет переменные, а заодно и возвращает новое значение flag. Сам-то макрос спрятан в далёких .h файлах, его не видно, и вот человек так ошибся. Этот программист напишет (может написать) что-то вроде вот такого:
И что получит? С вариантом через do-while (строка №4 НЕ закомментирована) он получит ошибку компиляции! А вот с вариантом через скобки он получит ворнинг (которых полно в «штатных» библиотеках, и на которые новички просто не обращают внимания), но всё нормально скомпилируется! Только работать будет вот так:
Т.е. локальный flag всегда истина, независимо от того, какое было значение у волатильного myFlag до вызова макроса. И ищи теперь этот баг, пока не посинеешь!
Т.е., давайте резюмируем: когда при написании «по жизни void» макроса мы использовали «по жизни void» конструкцию do-while, она нас выручила от ошибки в исполняемом коде, выдав ошибку при компиляции. А когда мы для «void макроса» использовали возвращающую значение конструкцию «круглые скобки», ошибки компиляции не случилось, зато ошибка переползла в исполняемый код, где искать её намного сложнее.
Т.е. ещё раз, каждый подход хорош для своего случая. На том основании, что какой-то подход где-то плох, нельзя отвергать его полностью. В одном из своих этюдов здесь, я использовал сравнение, которое мне очень понравилось, и которым я горжусь: «из того, что молотком неудобно красить стены, ещё не следует, что надо забивать гвозди малярной кистью».
Вот как-то так.
Ого, Евгений! Прям опера, не ожидал). Я всё понял. Да, действительно, нюансик есть. И, как бы, для себя сойдёт, а вот для "широкого применения" пожалуй не очень. Поэтому видать все и используют классику do-while.
ОК. Благодарю за труды. Как нибудь на досуге поищу Ваше сравнение.)