Неявные преобразования типа char

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DIYMan пишет:

ua6em пишет:

Вот, вот, как вообще у любителей к коим себя отношу что-то работает )))

Написано криво, вот и не работает, как надо, чему тут удивляться? В строке 14 в буфере может не быть ничего, т.к. до этого уже читали с буфера.

то-есть вся строка переданная , а это строка 'A123' уже считана?

В туториале пишут, что функция Serila.read() считывает следующий доступный байт из буфера, логично жеж предположить, что следующий байт после A это 1???
Так как функция продолжает работать дальше, откуда она эти байты достаёт?

Откуда достает данные строка 10?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ещё раз: в строке 14 - косяк. Для того, чтобы это понять - достаточно проговорить код, начиная с начала. В начале проверяется, "а есть ли хотя бы ОДИН байт в приемном буфере", затем этот байт читается, а в строке 14, если в приемном буфере был на момент проверки всего один байт - можем получить кукиш.

Код - переписывать, если ждёшь пакет определённой длины, влезающий в приемный буфер - то проще всего в if(Serial.available добавить проверку if(Serial.available() > 4 - как пример, условие сработает только при наличии 5 и больше уже принятых по UART байт.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DIYMan пишет:

Ещё раз: в строке 14 - косяк. Для того, чтобы это понять - достаточно проговорить код, начиная с начала. В начале проверяется, "а есть ли хотя бы ОДИН байт в приемном буфере", затем этот байт читается, а в строке 14, если в приемном буфере был на момент проверки всего один байт - можем получить кукиш.

Код - переписывать, если ждёшь пакет определённой длины, влезающий в приемный буфер - то проще всего в if(Serial.available добавить проверку if(Serial.available() > 4 - как пример, условие сработает только при наличии 5 и больше уже принятых по UART байт.

Я правильно понимаю - первый вызов функции Serial.read() чистит буфер полностью, так выходит из теста, куда он это сохраняет
Если бы я не работал с серийным портом ранее напрямую и не понимал на уровне железа как он программируется когнитивного диссонанса не возникало...

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

sadman41
Offline
Зарегистрирован: 19.10.2016

И вновь "специально написанный неправильный пример"... А правильный-то чего никто из "исследователей" не пишет?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

И вновь "специально написанный неправильный пример"... А правильный-то чего никто из "исследователей" не пишет?

а он и правильный одновременно, удалить 14,15 и 18 строки вставленные для исследования )))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ua6em пишет:

Я правильно понимаю - первый вызов функции Serial.read() чистит буфер полностью, так выходит из теста, куда он это сохраняет
Если бы я не работал с серийным портом ранее напрямую и не понимал на уровне железа как он программируется когнитивного диссонанса не возникало...

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

Serial.read не чистит буфер полностью. Посмотрите уже наконец исходники, если действительно интересуетесь вопросом - там всё более чем прозрачно написано. Да и в документации по Serial.read чётко сказано, что она делает.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

Я правильно понимаю - первый вызов функции Serial.read() чистит буфер полностью

Неправильно. Она читает один байт и ей глубоко начхать есть там в буфере что-то ещё или нет.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:

Я правильно понимаю - первый вызов функции Serial.read() чистит буфер полностью

Неправильно. Она читает один байт и ей глубоко начхать есть там в буфере что-то ещё или нет.

Можете пояснить, почему строка 14 не считывает следующий байт (из последовательности A123), говоря, что буфер пуст?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ua6em пишет:

ЕвгенийП пишет:

ua6em пишет:

Я правильно понимаю - первый вызов функции Serial.read() чистит буфер полностью

Неправильно. Она читает один байт и ей глубоко начхать есть там в буфере что-то ещё или нет.

Можете пояснить, почему строка 14 не считывает следующий байт (из последовательности A123), говоря, что буфер пуст?

Потому что была проверка только на наличие НЕНУЛЕВОГО кол-ва байт (один байт - тоже ненулевое значение) в приемном буфере, далее, выше строки 14 - ВОЗМОЖНЫЙ ЕДИНСТВЕННЫЙ байт в приемном буфере был вычитан, посему в строке 14 МОЖЕТ возникнуть ситуация, что приемный буфер УЖЕ пуст. Очевидно же.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:
почему строка 14 не считывает следующий байт (из последовательности A123), говоря, что буфер пуст?
Потому, что он пуст. Не пришло туде ещё ничего. Подождать надо.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:
почему строка 14 не считывает следующий байт (из последовательности A123), говоря, что буфер пуст?
Потому, что он пуст. Не пришло туде ещё ничего. Подождать надо.

слона то я и не приметил )))

Mannn
Offline
Зарегистрирован: 10.10.2020

Один хрен компилятор/язык кривой! Два дня разбирался почему программа скомпилированная Arduino 1.6.3 для ATmega328 работает с отрицательными числами типа Char без проблем, а скомпилированная Arduino 1.8.13 для ESP 8266 ни в какую! Пишет 255 вместо -1 и все тут. Думал что что-то происходит в процессе вычислений/присвоений.....ан нет!!! Оказывается Char  и  Signed char вообще ни разу не синонимы! Что за обновления такие? Каждый раз какую-то "пасхалочку" разработчики закладывают, а ты потом квесты проходи))) Я в шоке!

P.S. Для решения моей проблемы нужно было объявлять переменные как Signed char , а не как Char.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Так возьмите в привычку сразу для всех переменных знаковость указывать. Я вообще привык оперировать byte, word, unsigned long

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ох, не зря умные люди придумали 

int8_t, uint8_t, int16_t, uint64_t и т.д.   

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Mannn пишет:

Оказывается Char  и  Signed char вообще ни разу не синонимы! Что за обновления такие? Каждый раз какую-то "пасхалочку" разработчики закладывают, а ты потом квесты проходи))) Я в шоке!

Чтобы не "быть в шоке", нужно хотя бы иногда читать первоисточники. Char  и  Signed char в Си отродясь не синонимы. Вот прямо от Кернигана и Ритчи. И этот факт прямо отражен в стандарте языка.

Так что надо не "квесты проходить", а документацию читать.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Mannn пишет:
Один хрен компилятор/язык кривой!
А что в этом мире прямое? Солнечный луч и тот искривляется :-(
Mannn пишет:
Каждый раз какую-то "пасхалочку" разработчики закладывают, а ты потом квесты проходи))) Я в шоке!
Чтобы не проходить каждый раз квесты, нужно просто знать язык на котором пишете. См. #65

Green
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

Mannn пишет:
Один хрен компилятор/язык кривой!
А что в этом мире прямое? Солнечный луч и тот искривляется :-(


Кривой - не кривой... "че нам из него стрелять что ли.")

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Интересная тема, котел вроде не взорвался)) Правда и не управлял пока еще им. Сам в шоке как поделки месяцами работают)).

Вчера натолкнулся на непонятный мне тип unsigned char[] = "hello".  И чем byte от unsigned char и от uint8_t отличается?  Для преобразования строки в unsigned char[] использовал следующую конструкцию. 

String buf="ляля";
  unsigned char content[buf.length()];
  for (int i = 0; i < buf.length(); i++) {
    content[i] = buf.charAt(i);
  }

Все это для расчета MD5, в mbedtls/md5.h функция mbedtls_md5_ret принимает unsigned char поэтому и приходится переводить строку. Правильно я делаю, или есть какой более изящный способ без циклов?

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

Интересная тема и с примерами. Я про неявные преобразования вообще. Думаю тема достойна быть переделана в этюд для начинающих. Если бы p-a-h-a не поднял её я бы и не заметил эту тему.