Знатоки кода подскажите пожалуйста почему компилируется Код (C++): void loop() { lab: if (digitalRead(13)){goto lab;} } а вот так не компилируется Код (C++): void loop() { if (digitalRead(13)){goto lab;} lab: } и можно ли размещать метки перехода после того как них ссылаешься !?
Компилироваться должно в обеих случаях. По вопросу - да, можно. З.Ы. Попробуйте в некомпилируемом случае поставить точку с запятой после метки, т.е.: Код (C++): void loop() { if (digitalRead(13)){goto lab;} lab: ; }
за З.Ы. отдельное спасибо - вот и читай документацию в интернете - всю башку изломал ))) http://arduino.ua/ru/prog/Goto
А там просто неочевидно, что после метки должны быть операторы какие-либо, поэтому и такое поведение. В вашем некомпилируемом случае - после метки пустота, возможно, это баг парсера при построении AST, поэтому и не компилится, точка с запятой решает эту проблему, как добавление в дерево разбора ветки с пустым оператором. Как-то так.
Спасибо! Код (C++): void loop() { if (digitalRead(13)){goto lab;} lab: digitalWrite(13,1); } Если так то все ОК! У меня goto в теле процедуры стоит и он должен выносить из цикла в конец процедуры при определенном условии - поэтому больше там операторов нету
Ясно, что моё мнение никому не интересно, но я уже и забыл, когда возникала необходимость использовать goto. И в вашем случае, уверен, можно без него обойтись
Про дурной тон и "спагетти" я в курсе ))) Но иногда правила нарушаю если от этого улучшается читаемость кода - для меня это хобби и потому может возникнуть проблема если придется что-то поправить через месяц-два Если интересна вот вся процедура Код (C++): void USART_Receive() { start_Rx: sRX = millis(); //запоминаем текущее время while ( !(UCSR0A & (1 << RXC0)) ) // Ожидание поступления данных { dRX = millis() - sRX; //сколько ждем байт ? if (dRX > pRX) {goto pipec_Rx;} // связь пропала } Bincoming[CountArr] = UDR0; // Получить и возвратить данные из буфера CountArr++; // Увеличиваем счетчик входящих байт if (CountArr < 10) {goto start_Rx;} // Не все байты пришли digitalWrite(14, HIGH); // Получены все байты - зажигаем светодиод связи pipec_Rx:; // Вываливаемся сюда если связи нет } функция ждет поступления через UART пакета из 10 байт и если связь пропадает отваливается по TimeOut
Как минимум 1 goto можно убрать спокойно. Даже строк меньше будет: Да собственно и второй можно. Не нужно использоваться goto... Просто не нужно. Да удобно, но нет, не нужно. Кому то хобби начинает доход приносить, но для этого точно нужно делать качественно. Код (C++): void USART_Receive() { for( int i =0;i<10;i++) { sRX = millis(); //запоминаем текущее время while ( !(UCSR0A & (1 << RXC0)) ) // Ожидание поступления данных { dRX = millis() - sRX; //сколько ждем байт ? if (dRX > pRX) {return;} // Вываливаемся сюда если связи нет } Bincoming[i] = UDR0; // Получить и возвратить данные из буфера } digitalWrite(14, HIGH); // Получены все байты - зажигаем светодиод связи }
Да я не спорю - тут если поднапрячься можно еще 2/3 операторов выкинуть - проблема в том что я еще не знаю как это будет работать целиком - может я еще сюда процедуру обработки потери связи запихну (а может нет) - мне важен результат, а он будет хоть с гото хоть без него мне как любителю пофиг (особенно учитывая тормознутость самого радиоканала) - пока это отладочный код и там очень много довольно криво написанных за то интуитивно понятных и простых секций. Если писать "по православному" нужно вообще сделать чтобы функция возвращала 0 если ничего не пришло и 1 если все ОК, а у меня на 14м пине светодиод висит - криво - за то сразу видно ок или не ок ))) и Boolean не нужен
С гото можно лихо влететь, если пихать его куда ни попадя. Например из тела цикла куда то еще. Или из тела функции. Есть вот такой кашерный вариант, как пример.
Ну Break то тут мне не совсем подходит потому-что вываливаться то мне нужно именно из всей процедуры (собственно говоря из-за этого она была и сделана) следующая попытка запроса данных поступит только через 0.5 секунды и должна она начинаться с нуля - ORLENOK предложил самый оптимальный вариант (в ней 2 проверки собственно что вообще что-то приходит и что пришло все а не часть)
Как-то так правильно, если массив объявлен статически. Код (C++): uint8_t USART_Receive() { for(uint8_t i = 0; i < sizeof(Bincoming); i++) { sRX = millis(); while ( !(UCSR0A & (1 << RXC0)) ) if (millis() - sRX > pRX) return i; Bincoming[i] = UDR0; } digitalWrite(14, HIGH); return sizeof(Bincoming); }
именно для этого придуман оператор return. В самом первом коде поставьте его вместо goto lab Код (C++): void loop() { if (digitalRead(13)){return;} }