Массив enum
- Войдите на сайт для отправки комментариев
Втр, 25/02/2014 - 17:14
Есть перечисление ID (состояний) устройства:
enum states { CLEAN, DRIVE, SENSORS, EFFECT1, EFFECT2, EFFECT3};
И есть соответствующие им сообщения:
const char *menuPage1[]= { "Clean plate", "Working...", "Sensor settings", "Effect 1", "Effect 2", "Effect 3" };
Сейчас чтобы что-то подправить, надо аккуратно сличать количество и последовательность пунктов.
Есть ли способ их объединить в одну структуру/массив/что-то еще, чтобы было наглядное соответствие ID обозначения?
Т.е. что-то вроде этого:
{ { CLEAN, "Clean plate" } { DRIVE, "Working..." } { SENSORS, "Sensor settings" } { EFFECT1, "Effect 1" } { EFFECT2, "Effect 2" } { EFFECT3, "Effect 3" } };
Примерно так
Спасибо.
А как ID теперь использовать в switch...case?
Раньше было switch (states) {case CLEAN: ... }
Добавить функцию, которая по состоянию будет искать в массиве соответствующий текст и возвращать указатель на этот текст. Универсально, при добавлении нового состояния, функция будет работать
плохая реализация, лучше строки сделать как переменные.
ну а потом уже много if
плохая реализация, лучше строки сделать как переменные.
ну а потом уже много if
как я понял, но ему нужно сравнивать с ID, те те перебирать в цикле все элементы
pages[i].state для i=0; i = maxindex
и выразить maxindex через sizeof или SIZEOF ???
Как это сейчас:
И этот заголовок "Working...", выводимый по текущему состоянию DRIVE, используется еще в одном месте. Т.е. чтобы что-то подправить, приходится прыгать по трем кускам кода . Было бы удобнее, если их объявление будет легкочитаемо и в одном месте, как предложил ites. И далее программно только выбирать через switch нужные строки. Вот только как синтаксически выразить в case элемент DRIVE из menu_t pages[] (если по примеру из сообщения #2) - я пока не знаю.
И далее программно только выбирать через switch нужные строки. Вот только как синтаксически выразить в case элемент DRIVE из menu_t pages[] (если по примеру из сообщения #2) - я пока не знаю.
для swich нужны метки=константы,
можно case A:
и нельзя A[i]: // но если const int A[]={const1, const2 ...}; ?
После применения структуры доступны элементы массива, те в общем случае переменные. Enum в действительности перечислчяемые константы, но поймет ли компилятор как константу pages[i].state ?
Если не поймет, попытаться обойти при помощи препроцессорных директив?
спросите лучше у maksim
ну есть же в сети сотни тысяч класических реализаций....
Вам нужно только 2 функции и никаких массивов или других конструкций ибо будет неудобно и не универсально.
А далее пользуйтесь этим всем без заморочек где угодно и сколько угодно раз.
Хотя тут есть очень спорные моменты, ибо этот код проверят полное совпадение, если вам надо без учета регистра то придется добавить чуть кода
Ну перевод значения в строку это совсем просто, это либо ваш массив, но я бы просто сделал switch...case, будет просто несколько гибче.
З.Ы. Я только никак не могу понять зачем вам строки переводить в значения ? Обычно такое возникает только при общении с внешним миром по текстовому протоколу, но тогда это будет самая маленькая проблема, и вы на разборе текста огребете столько проблем.
мне не нужно строки переводить в значения (в enum как раз не строки, а числовые последовательные значения: CLEAR это синоним 0, DRIVE = 1 и т.д.). Через enum и case это легко читается в коде и обратывается проходом в цикле при необходимости. Через if уже менее наглядно.
Мне нужно: если текущее состояние DRIVE (или 1, т.к. в enum они все равно пронумерованы), вывести в первой строке соответствующий заголовок. Т.к. это состояние и заголовок не меняются в трех разных функциях, хочется не прописывать одно и то же в трех местах, а ради удобства просто держать связку "состояние, заголовок" визуально рядом (в какой-то конструкции) и тупо в тех функциях: "Если состояние А1, показать строку А2". А знаний пока не хватает...
Не понимаю - изначально сделали массив структур для упорядочиввания и автоматического соответствия данных, а также во избежание ошибок.
Но воспользоваться enum значениями элементов массива в операторе switch-case не можете. В чем суть темы или цель по ходу действия поменялась ?
увы, "массив структур" пока не удалось сделать
есть отдельно
enum
states
и отдельноconst
char
*menuPage1[]
Если их соединить в
typedef
struct
{
02
enum
states state;
03
const
char
*str;
04
} menu_t;
то как в case использовать элементы из нее? На любые варианты компилятор гругается.
Вот проверил, работает, но определение enum в одном файле с функцией с параметром типа enum приводит к ошибке компиляции - баг уже описывали тут, пришлось enum описать в хидерном файле enum.h и все заработало (писал для тестирования, не пинать за огрехи):
жесть.... просто нереальная жесть.... зачем все эти танцы с бубуном....
зачем городить такой огород с поиском.
Я это не компилил, сейчас просто не могу, но думаю что даже enum скомпилиться без проблем :-) в ваших примерах похоже typedef используется некооректно.
Вся жесть для того, чтобы протестить первый предложенный ответ, а заодно ответить на последний вопрос автора. Да мне и самому захотелось изучить эти конструкции :)
Вся жесть для того, чтобы протестить первый предложенный ответ, а заодно ответить на последний вопрос автора. Да мне и самому захотелось изучить эти конструкции :)
О да месье знает толк в извращениях :-)
главная идея была в автоматизации соответствия текущего state и соответствующего указателя на строку
используя то, что state являются перечисляемыми со значениями 0,1,2,3 ...., можно использовать state как индекс массива, код не проверял и возможно придется сделать явное преобразование типа (int)state, в идеале switch-case сведется к одной строчке: return (pages[state].str);
главная идея была в автоматизации соответствия текущего state и соответствующего указателя на строку
используя то, что state являются перечисляемыми со значениями 0,1,2,3 ...., можно использовать state как индекс массива, код не проверял и возможно придется сделать явное преобразование типа (int)state, в идеале switch-case сведется к одной строчке: return (pages[state].str);
Ну и пришли вы к тому, с чего начали - enum и и массив строк ! :)
Только там неявно номер в массиве соответствовал номеру енум, а теперь просто изменится вид объявления вашего массива строк. А это могли и раньше использовать: return (pages[state]);
ура, меня наконец-то поняли :) радует, что код оптимизируется на глазах.
Всем большое спасибо, сейчас буду разбираться с каждым вариантом.
Вот проверил, работает, но определение enum в одном файле с функцией с параметром типа enum приводит к ошибке компиляции - баг уже описывали тут, пришлось enum описать в хидерном файле enum.h
эта ошибка в компиляторе еще не устранена ?
Такой тест получился:
С интересом продолжаю наблюдать за развитием темы. Продолжайте... :)
Константы в enum по умолчанию отсчитываются с 0 и увеличиваются на 1. Их можно использовать просто как индекс в массиве, если массив упорядочен. Если не упорядочен, то по нему нужен поиск.
да, так и писать
case CLEAN:
а если в switch предусмотрите формальное преобразование переменной к типу к STATE,
то компилятор должен заметить в "case" любую "инородную" константу, например CLEAN1 не входящую в список enum STATE ; (CLEAN1 может иметь допустимое численное значение 0,1,2,.... , но не вхрдить в нужный список enum)
Такой тест получился:
Усложняете программу и понижаете ее надежность и читаемость. Берете на себя рутинные функции компилятора - сами определяете размерность массива
char
menu[10][32];
Малейшая ошибка при копировании строки, связанная с ее длиной и выходом за пределы допустимого индекса и вы затрете смежную область памяти.
Усложняете программу и понижаете ее надежность и читаемость. Берете на себя рутинные функции компилятора - сами определяете размерность массива
char
menu[10][32];
Малейшая ошибка при копировании строки, связанная с ее длиной и выходом за пределы допустимого индекса и вы затрете смежную область памяти.
Так мне то этот гемор не нужен, у меня нет запар с сопоставлением порядковых номеров и строк :)
Все для афтора топика!
У меня все подходы системные. Читайте внимательтно тексты программ, там все сказано и про тестирование и про ожидаемые глюки. И уж простите, но ваше мнение меня совершенно не интересует. Без обид.
вот оно, решение что искалось изначально: http://habrahabr.ru/post/241941/ :)
Привет! Удалось реализовать идею по этой статье с хабра? Можно взглянуть на ардуино-вариант для решения исходной задачи?