Официальный сайт компании Arduino по адресу arduino.cc
switch и структурированный массив - ошибка expression must have a constant value -- attempt to access run-time storage
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Вс, 17/02/2019 - 16:19
Добрый день! Прошу помочь знатоков С++ и Arduino. Записываю массив данных в структурированный массив. После чего мне необходимо обработать данные оператором switch. Фрагмент кода:
#include <Arduino.h> const uint8_t cntPins = 8; struct listData_t { const uint8_t pinNumsber; const uint8_t pinID; }; const listData_t pins[cntPins] = { {32, 2}, {34, 3}, {36, 4}, {38, 14}, {40, 15}, {42, 11}, {44, 13}, {46, 5} }; void setup() { Serial.begin(115200); Serial.println(F("Start...")); for (uint8_t i=0; i<cntPins; i++) { Serial.print(pins[i].pinNumsber); Serial.print(F("\t")); Serial.println(pins[i].pinID); } } void loop() { delay(1500); for (uint8_t i=0; i<cntPins; i++) { switch (pins[i].pinID) { case pins[0].pinID: Serial.print(F("pinNumber > ")); Serial.println(pins[i].pinNumsber); break; } } }
При компиляции возвращаются 2 ошибки:
expression must have a constant value -- attempt to access run-time storage
the value of 'pins' is not usable in a constant expression.
Если в case поставить const uint8_t N, то копилируется без ошибок и код работает. Кто может подсказать в какую сторону "копать"?
А вот чем Вам двумерный массив не нравится? Или там более глобальные замыслы?
Попробуйте в 3 строке проименить #define cntPins 8
здесь
case
pins[0].pinID:
должна быть целая константа
Например
case 10: ....
case 'a': ...
и т.д.
здесь
case
pins[0].pinID:
должна быть целая константа
Например
case 10: ....
case 'a': ...
и т.д.
Я это понимаю, вопрос, есть вариант подставить в case целую константу, получив ее из массива?
Получается, мне нужно или дублировать константу, которую подставлять в case, или уходить на одномерные массивы, что очень не удобно и не желательно, или сначала, перед switch "выдергивать" данные из массива в локальные переменные, которые подставлять в case, что тоже, как-то кривовато... Может есть, какой-то вариант, я не профессионал в данном вопросе, поэтому и прошу подсказку в какую сторону копать...
А вот чем Вам двумерный массив не нравится? Или там более глобальные замыслы?
Попробуйте в 3 строке проименить #define cntPins 8
количество записей в массиве - не проблема, проблема в целочисленной константе, которую "кушает" case...
Да, задумка более глобальная, нежели во фрагменте кода...
Я это понимаю, вопрос, есть вариант подставить в case целую константу, получив ее из массива?
Константа в case должна быть доступна на момент компиляции. Т.е. напрямую или через подстановку. Но никак не по вычисляемому на этапе исполнения индексу массива. Select-case в объектном коде выглядит набором джампов (считай goto), поэтому адреса "приземлений" должны быть вычислены при компиляции.
Получается, мне нужно или дублировать константу, которую подставлять в case, или уходить на одномерные массивы, что очень не удобно и не желательно, или сначала, перед switch "выдергивать" данные из массива в локальные переменные, которые подставлять в case, что тоже, как-то кривовато... Может есть, какой-то вариант, я не профессионал в данном вопросе, поэтому и прошу подсказку в какую сторону копать...
Чтобы понять куда копать - надо узнать для чего копать. Если бы граф Монте-Кристо копал без понимания направления, то скелет его нашли бы в каземате.
Ну не обязательно же через switch - case делать. Можно ведь и через if - else if конструкцию.
Ну не обязательно же через switch - case делать. Можно ведь и через if - else if конструкцию.
Громостко и неудобно получается, если if и else if использовать...
Чтобы понять куда копать - надо узнать для чего копать. Если бы граф Монте-Кристо копал без понимания направления, то скелет его нашли бы в каземате.
Получается выход один, вычислить все переменные, хранящиеся в многомерных массивах до их использования в операторе switch и case... Другого выходе нет?!
Для чего копать:
1. Хранить данные в многомерном структурированном массиве
2. Использовать switch и case используя данные их многомерных структурированных массивов
2. Использовать switch и case используя данные их многомерных структурированных массивов
Использовать для... <тут пример использования>
Громостко и неудобно получается, если if и else if использовать...
Что же там громоЗДкого! Даже компактнее получится. А если нужны условные break-и, то их можно ретурном заментить, если оформить в функции.
Использовать для... <тут пример использования>
Как пример использования:
при этом RXdata это данные полученные по UART или RS-485
На поверхности лежит поиск в цикле соответствия RXData и idBTN. Switch нацеливается на переменную, в которую помещается найденный индекс элемента массива, который соответствует условию. Все индексы определены на этапе компиляции и проблемы не возникнет. Можно через define дать им осмысленные имена.
На поверхности лежит поиск в цикле соответствия RXData и idBTN. Switch нацеливается на переменную, в которую помещается найденный индекс элемента массива, который соответствует условию. Все индексы определены на этапе компиляции и проблемы не возникнет. Можно через define дать им осмысленные имена.
Да, всё верно, полученные внешние данные я сравниваю с id кнопки, чтобы выполнить то или иное действие по нажатию локальной кнопки. Если явно задать имена, тогда при создании многомерного массива, писать в него не физические значения id, а имена, тем самым запишеться значение присвоеное через #define.
как-то так, или всё же есть более правильный способ, через #define?
Я имел в виду более сложный вариант, но, если idNameX никогда не будет несовместимого с case типа, то можно и на этом остановиться.
Я имел в виду более сложный вариант, но, если idNameX никогда не будет несовместимого с case типа, то можно и на этом остановиться.
idNameX - всегда число (uint8_t или const uint8_t), как id компонента.
А какой более сложный вариант, если не сложно, пример дайте пожалуйста
Я его описал выше - поиск в цикле. Искомая строка сравнивается, например, с buttons[i].nameBTN, совпало - из цикла выскакиваем, найденный индекс (i) суём в switch.
Я его описал выше - поиск в цикле. Искомая строка сравнивается, например, с buttons[i].nameBTN, совпало - из цикла выскакиваем, найденный индекс (i) суём в switch.
Спасибо! Невнимательно прочел тот пост.