не могу понять свою ошибку

Ulliss
Offline
Зарегистрирован: 16.09.2019

собственно осваиваю массивы и операторы выбора Switch

и на пробном скетче впал в ступор.

что я сделал не так? прошу ткнуть носом: какое первичное выражение я пропустил?

алгоритм хочу считать так: 

если разница между 10ым и 1ым значением в матрице меньше "-5", то тренду присвоить значение "4"

если от "-2" до "-5", то тренду присвоить "3" и т.д.

Это понадобится мне в последующем заполнении скетча выводом на экран и т.п.

пишет ошибку:

C:\Users\Documents\Arduino\my sketchs\trend\trend.ino: In function 'void loop()':
trend:23:11: error: expected primary-expression before 'case'
   (-5) >= case: trend = 4; // неуклонно падает
           ^~~~
trend:25:10: error: expected primary-expression before 'case'
   (-5) < case <=(-2): trend = 3; // уменьшается
          ^~~~
trend:27:10: error: expected primary-expression before 'case'
   (-2) < case <= 2:    trend = 5; // без изменений
          ^~~~
trend:29:7: error: expected primary-expression before 'case'
   2 < case <= 5:  trend = 1; // повышается
       ^~~~
trend:31:8: error: expected primary-expression before '>' token
   case > 5: trend = 2; // неуклонно растет
        ^
Несколько библиотек найдено для "DHT.h"
 Используется: C:\Users\Documents\Arduino\libraries\DHT
Несколько библиотек найдено для "Wire.h"
 Используется: C:\Program
exit status 1
expected primary-expression before 'case'
 
#include "DHT.h"       // подключаем библиотеку для датчика
DHT dht(A0, DHT11); // сообщаем на каком порту будет датчик
#include <Wire.h>
long temperature, temperature_massive[10]; // переменная температуры и массива температур из 30 значений
byte trend; // переменная тенденции

void setup() {
  Serial.begin(9600); // подключаем порт монитора
  dht.begin();                           // запускаем датчик DHT11
  for (byte i = 0; i < 10; i++) {   
    temperature_massive[i] = temperature;  // забить весь массив текущими значениями температуры
  }
}

void loop() {
      temperature = dht.readTemperature();
    for (byte i = 0; i < 10; i++) {                   
      temperature_massive[i] = temperature_massive[i + 1];     // сдвинуть массив на один шаг назад (кроме последнего элемента)
    }
    temperature_massive[10] = temperature;                    // последний элемент массива теперь - новая температура
  int a = (temperature_massive[10] - temperature_massive[1]);
  switch (a) {
  (-5) >= case: trend = 4; // неуклонно падает
  break;
  (-5) < case <=(-2): trend = 3; // уменьшается
  break;
  (-2) < case <= 2:    trend = 5; // без изменений
  break;
  2 < case <= 5:  trend = 1; // повышается
  break;
  case > 5: trend = 2; // неуклонно растет
  break;
  } 
Serial.print ("trend = ");
Serial.println (trend);
delay (5000);
}

 

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Открываем любое пособие по С или С++ и смотрим синтакис оператора switch

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Шах и мат, сторонники эволюции и естественного отбора! А иначе как объяснить факт того, что ТС дожил до настоящего времени? 

Вот и я говорю: на всё воля Б..жия и пути Господни неисповедимы!

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

а цикл 10-12, с красноречивым комментарием ?

а 17-20 и 21 с выходом за границы?

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

Да, ладно, вам, мужики. У меня вот уже фраза

Ulliss пишет:
не могу понять свою ошибку

вызвала уважение.

Согласитесь, чаще в проблемах виноваты не свои ошибки, а китайскость платы :)

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

И американские компиляторы.)

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

Вот, только помянул не к месту и давеча столкнулся.) Должно выдать v = 1234, а выдаёт 3412.
Не Ардуино - ХС8. С GCC всё ОК.

  eeprom_write_byte(0, 0x34);           //little-endian
  eeprom_write_byte(1, 0x12);
  
  uint8_t i = 2; 
  uint16_t v = eeprom_read_byte(--i)<<8 | eeprom_read_byte(--i);

Где тут подвох? Вроде всё красиво. ЕвгенийП, есть мысли?)

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

Green пишет:

...Должно выдать...

А кому должно и почему?

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

Мне бы так хотелось.) Слева направо ведь или нет?

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

А что, кто-то обещал?

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

Ну да, префиксный декремент справа-налево. Но тогда отчего у Ардуино наоборот?

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

Green пишет:

Ну да, префиксный декремент справа-налево. Но тогда отчего у Ардуино наоборот?

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

виновата китайскость платы :)

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

Особенно когда проверяешь в эмуляторе.)

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

пожалуй подпишусь )))

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

Green пишет:

Особенно когда проверяешь в эмуляторе.)

Да, в этом случае особенно.

А вообще, может настроение не то, но что-то троллинг не смешной какой-то.

Green пишет:

Вот, только помянул не к месту и давеча столкнулся.) Должно выдать v = 1234, а выдаёт 3412.
Не Ардуино - ХС8. С GCC всё ОК.

  eeprom_write_byte(0, 0x34);           //little-endian
  eeprom_write_byte(1, 0x12);
  
  uint8_t i = 2; 
  uint16_t v = eeprom_read_byte(--i)<<8 | eeprom_read_byte(--i);

Где тут подвох? Вроде всё красиво. ЕвгенийП, есть мысли?)

Специально попробовал ... похоже, подвох в том, что Вы неудачно шутите.

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

Так он какой-то компилятор другой в сарае отыскал - ХС8. С ним, говорит, little endian в big endian превращаются.

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

Нет никаких шуток. Вы невнимательно читаете.) Проблема не в Ардуино, проблема с ХС8 - компилятором для PIC16. А там 3412, хотя аналогичный фрагмент Ардуино выдаёт 1234. И вот вопрос, кто неправ.)

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

sadman41 пишет:

Так он какой-то компилятор другой в сарае отыскал - ХС8. С ним, говорит, little endian в big endian превращаются.


Ну почему в сарае? Это самый нормальный компилер для PIC среднего семейства.

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

Green пишет:

Ну да, префиксный декремент справа-налево. Но тогда отчего у Ардуино наоборот?

Так дело не в декременте, а в том, что компилятор исходит и того, что преобразование из a*b в b*a с точки зрения математики является тождественным. А то, что программист совершил грубую ошибку, совместив в одном выражении два подвыражения, имеющих каждый побочный эффект, причем так, что этот эффект зависит от порядка вычисления выражения, от компилятора никак не зависит.

Компилятору неизвестно, что хотел написать программист, он может оперировать только с тем, что программист написал.

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

Вы можете разложить (разжевать) это выражение с точки зрения компилятора?

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

andriano, видимо, намекает на то, что компилятор вправе eeprom_read_byte(--i)<<8 | eeprom_read_byte(--i); выполнять сзаду.

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

Так я ж не против. Мне только непонятна последовательность выполнения.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Ты серьезно?

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

Green пишет:

Так я ж не против. Мне только непонятна последовательность выполнения.

надо спросить армянское радио

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

а так?

uint8_t i = 2; 
uint16_t v = eeprom_read_byte(--i)<<8;
v=v | eeprom_read_byte(--i);

 

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

BOOM пишет:

Ты серьезно?

Да. Непонятно почему для одного компилятора так, а для другого - по другому. Просто пришлось в тему.)

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

Green пишет:

Так я ж не против. Мне только непонятна последовательность выполнения.

Я сначала не заметил про другой компилятор и посчитал сообщение троллингом. Сорри.

А так-то всё нормально, вполне допустимо, что в разных компиляторах по-разному, т.к. стандарт не определяет последовательность вычисления операндов:

"Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced ... The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a memory location (4.4) is unsequenced relative to either another side effect on the same memory location or a value computation using the value of any object in the same memory location, and they are not potentially concurrent (4.7) , the behavior is undefined"
(ISO/IEC 14882:2017 разд. 4.6(17) стр. 14)

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

Где то такое у меня мыслях и витало, но хотелось какого то определения от знающих.) Спасибо!
Получилось так, что я аналогичный код делал под Ардуино и всё было ОК, а тут вот столкнулся с другим МК и на тебе!)
Вот так дураком и помрёшь.(

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

Кстати, порядок вычисления аргументов функции тоже не определён.

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

В моём случае сначала уменьшаем аргумент, затем передаём параметр. Разве нет?

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

Green пишет:

Где то такое у меня мыслях и витало, но хотелось какого то определения от знающих.) Спасибо!
Получилось так, что я аналогичный код делал под Ардуино и всё было ОК, а тут вот столкнулся с другим МК и на тебе!)
Вот так дураком и помрёшь.(

будьте проще - пишите в лоб )))

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

ua6em пишет:

а так?

uint8_t i = 2; 
uint16_t v = eeprom_read_byte(--i)<<8;
v=v | eeprom_read_byte(--i);

 

Все остальные чёткие указания - без вопросов, всё логично.

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

Green пишет:

ua6em пишет:

а так?

uint8_t i = 2; 
uint16_t v = eeprom_read_byte(--i)<<8;
v=v | eeprom_read_byte(--i);

 

Все остальные чёткие указания - без вопросов, всё логично.

видимо мой учитель твой компилятор писал )))

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

Green пишет:

В моём случае сначала уменьшаем аргумент, затем передаём параметр. Разве нет?

это да. Я говорю про порядок вычисления аргументов.

Например f(++n, --n); ХЗ какой из аргументов будет вычисляться первым, а какой вторым.

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

ua6em пишет:

видимо мой учитель твой компилятор писал )))

Да ладно!)
"Microchip MPLAB XC8 MPLAB XC16 MPLAB XC32 Три компилятора MPLAB XC для 8-, 16- и 32-разрядных микроконтроллеров позволяют увеличить скорость выполнения кода на 30% и уменьшить размер кода на 35%

Компания Microchip сообщила о выходе серии Си компиляторов MPLAB XC для всех 900 микроконтроллеров с 8/16/32-разрядной архитектурой и цифровых сигнальных контроллеров. Компиляторы MPLAB XC8, XC16 и XC32 упрощают выбор программиста и разработку приложений на базе микроконтроллеров, предоставляя три уровня оптимизации: Бесплатный (Free), Стандартный (Standard) и Продвинутый (Pro). Pro версии имеют оценочный режим на 60 дней. Компиляторы XC мультиплатформенные и работают под Linux, Mac и Windows.""

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

Green пишет:

Так я ж не против. Мне только непонятна последовательность выполнения.

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

Вариант, где последовательность выполнения определена, приведен в сообщении №24.

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

Ну, так мы договоримся до того что и оптимизацию нам самим тоже нужно делать.
Я ж говорю, смутило то что с одним так, а с другим иначе. Потому и вопрос возник.

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

Еще раз: с конструкциями, имеющими побочный эффект, обращаться нужно крайне осторожно.

А оптимизацию - да: самая эффективная оптимизация - алгоритмическая, ее нужно делать именно "нам самим", компилятор ее за нас делать не может.

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

в MPLAB я только ассемблером пользовался да и из пиков только для pic16F84

Ulliss
Offline
Зарегистрирован: 16.09.2019

всем спасибо. разобрался с синтаксисом.

массив не до конца победил.=(