двумерный массив с разными типами данных
- Войдите на сайт для отправки комментариев
Пт, 27/06/2014 - 11:53
Есть ли способ создать двумерный массив с разными типами данных?
на подобный ругается.
char* fan [2][5] = { {"auto","low","mid","high","fix"},{B101,B100,B010,B001,B000} };
в javascript - да.
В cи вряд ли.
Вообщем-то можно... (приведение типов и т.п.), только "не нужно это".
Глядя на данный пример, тут явно просится stuct и массив уже структур. Структуры для того и придуманы. Что-бы и в коде потом не магию типа fun[0] [3] и f[1][3], писать, а осмысленно понятное типа fun[3].name и fun[3].value
Получается тогда как-то так
только вот уже на 15 значений данной структурой не воспользоваться... переинициализировать, видимо, надо будет
Вопрос. Если в 15 значные массивы кидать по 5 значений, переизбытка используемого места не будет?
>Вопрос. Если в 15 значные массивы кидать по 5 значений, переизбытка используемого места не будет?
Будет. Впустую расходуемое место.
Лучше объявлять name[] - пусть компилятор сам выясняет какой длины строку вы пихаете. Да и char*, в явном виде вы явно указали зря.
Заодно не ошибетесь и в другую сторону (длинную строку, в малый массив).
Нет. Все не так. Сами-то код пускали
>
int
value[5];
При объявлении типа структура, мы описываем ОДИН элемент. Один вентилятор. int value[5] - вы, фактически сказали, что у вас КАЖДЫЙ вентилятор, будет иметь ПЯТЬ интовых значений. Это действительно так? То же и с именами. Вы сказали что каждый вентилятор будет иметь пять имен.
>
struct
cond fan =
И где тут объявление МАССИВА структур? Объевления переменной типа cond, вижу, а массива.
Вообщем вам нужно при описании cond, описать ОДИН вентилятор.
А потом переменную fan объявить как МАССИВ элементов типа cond.
И работать с ним соотвественно (и инициализация, и доступ к элементам). Я как писал? fun[3].name - имя четвертого вентилятора, а у вас? fan.name[2] - третье имя единственного вентилятора.
Если уж, так хочется иметь отдельно имена, отдельно значения, то собственно зачем их объединять?
Можно тогда и без структур.
Просто два массива:
И работать с ними names[0] - имя первого, values[0] - значение первого.
из справочникив почитал о вот таком вот виде составления:
где потом под type и подразумевается fan и другие состояния (mode и temp)
Вентилятор один, у него пять состояний (name), каждое из которых имеет значение (value).
Когда пытаюсь задать name[] - компилятор ругается (создает массив с 1 значением и соответсвено, когда даешь ему 5 - не лезет).
В принципе, я думал об независимых массивах, просто хотелось их как-то привязать друг к другу для удобства использования.
По поводу char* - задаю массив строк (прочитал тут же на сайте в справочнике)
То что было написано ранее компилятор вроде отрабатывает без ошибок.
Или я всё же чего-то не понимаю...
Еще раз. stuct - у вас описывает СОСТОЯНИЕ. А состояние имеет ОДНО имя. И ОДНО значение.
Поэтому "(создает массив с 1 значением и соответсвено, когда даешь ему 5 - не лезет)" - совершенно верно. Так и должно быть.
А после того, как вы описали структурой как выглядит ОДНО состояние, вы объявляете МАССИВ СТРУКТУР. Массив состояний.
Для кого писалось:
Вообщем вам нужно при описании cond, описать ОДИН вентилятор.
А потом переменную fan объявить как МАССИВ элементов типа cond.
???
Вы же упорно, продолжаете пытатся запихнуть масивы внутрь структуры. У вас должны быть не массивы в структуре, а структуры в массиве.
Ну ок. Не вентяляторов у вас много, а состояний. Суть это не меняет. Кстати почему бы тогда структуру не назвать state, и массив состояний states[]? Или что-бы если потом появятся состояние еще чего-нибудь не путстаться и сразу обозвать funState_t и funStates[]
Прошу прощения, что-то совсем туплю, можете привести пример того как Вы это видите? может хоть так разберусь...
Неэ... так просто вы не отделаетесь. Если не получается "сразу понять", значит еще больше дробить задачу нужно.
Давайте отдельно разбиратся со структурами, отдельно с массивами.
Вначле со структурами. Забудте что у вас есть пять штук.
Опишите стуктуру описывающую ОДНО состояние. И объявите переменную этого типа.
Опиратся можете на этот туториал: Arduino Playground - Struct Resource
И показывайте что вышло.
так?
Так.
Ну если не считать, что у вас постоянно путаница в именах/терминах. То вы говорите что у вас "состояния", то в называете это "кондиционер", то "вентитялтор".
Главное что вы тут должны понять: слово struct - это описание ТИПА. Есть встроенные типы int,byte, boolean. Но нам их не хватило. Пришлось свой придумывать. И вот конструкцией struct мы описали "как он выглядит".
После того как компилятор узнал про этот тип, дальше мы можем пользоватся им так же как и встроенными типами.
Например объявили "cond fun" - объявили переменную "fun" имеющую тип "cond". То есть - заствили выделить память под одно char* и один name.
OK. Теперь давайте несколько штук попробуем (пока без массивов). Как мы объявим, несколько переменных типа cond? Скажем переменные fun1, fun2, fun3? (подсказка: никаких отличий от встроенных типов. синтаксис - полностью аналогичный).
Вопрос. Если в 15 значные массивы кидать по 5 значений, переизбытка используемого места не будет?
всмысле, если объявить [15] а в реале написать 5?
компилятор 5 и нарисует. остальные отбросит.
Ну вроде про структуру состояние я не говорил...
Говорил про состояния работы этого cond (кондиционер - наверное надо было расписать чтобы не вводить в заблуждение) :) (аналоги переменной fan - вентилятор (режим работы вентилятора) (не fun - веселье), т.е. mode (режим работы) и temp (температура работы))
Т.е. fan - у меня получается как одно из состояний работы кондиционера.
Ну, так как мы объявим несколько переменных fun1, fun2, fun3?
О... круто :) Все верно.
Теперь, временно забываем про структуры и разбираемся с массивами.
Предположим у нас есть три штуки целочисленных переменных. В которых мы при инициализации ложим числа 10, 50, 125.
Вообщем объявлено у нас что-то такое:
Задача: переписать это с использованием массива. Что-бы вместо трех переменных myVar1,myVar2,myVar3 была одна переменная-массив myVars.
Как вы это сделаете?
массив (array)
Супер. А теперЬ, вот точно так же, абсолютно аналогично, сверните в массив вот этот свой код:
Что-бы вместо трех переменных fun1,fun2,fun3 была одна переменная-массив funs.
чёт я не догоняю, а чем не устраивает собственно предложеный ТС вариант со структурами? Вполне удобный и рабочий вариант.
чёт я не догоняю, а чем не устраивает собственно предложеный ТС вариант со структурами? Вполне удобный и рабочий вариант.
Давайте чуть позже, ok? Cразу с двумя непонимающими - тяжко ;)
cond fans[3]={{"low", B101},{"mid", B111},{"high", B110}};
массив структур...
так а структура массивов чем хуже?
я тоже думаю ничем не хуже. тем более она у вас уже написана, берите и пользуйтесь. )
cond fans[3]={{"low", B101},{"mid", B111},{"high", B110}};
Ну вот и все.
Теперь у вас есть, как вы и хотели изначально, массив. В котором есть хранится два типа данных.
Скажем вам нужно вывести имя второго, состония serial.println(fans[1].name), или значение первого serial.println(fans[0].value);
Можно for-ром, по ним пробежатся. Можно завести еще одну переменную в которой хранить текущий режим вашего вентилятора.
И, скажем где-то в Loop делать analogWrite(fans[currentMode].value));
А одновременно выводит на экран имя текущего режима lcd.print(0,0, fans[currentMode].name);
И, скажем кнопками (или по таймеру), просто менять режим изменяя циферку в currentMode (естественно следя за тем что-бы она не вышла за границы массива).
Это не "по другому", это и есть то к чему мы пытались привести топикстартера. Только что-бы он сам к этому пришел, а не "вот скопируй себе готовую магию".
так а структура массивов чем хуже?
Тем что в этом случае, по сравнению с двумя массивами, она просто "излишний синтаксический шум". Никаких дополнительных плюшек, кроме того что нужно больше кода написать.
Тем что в этом случае зазор между кодом и семантикой и синтаксисом - больше.
В том что в этом случае не возникает понимаение как работать с массивами структур.
В том что если нужно, скажем, добавить еще одно состояние, то мы должны будем его "добавить расписать" в два разных места, а не в одно. В том что "закоментить" или copy-paste одно состояние - трудней.
У нас части одной, по сути, "сущности" размазны по разным массивам. А если полей будет 10-ток? 10-ть массивов лепить? А если, нужно будет скажем передать в функцию в качестве параметра?
Сейчас-то просто... void myFunc(cond* arg); А с массивами как? Не ну можно, конечно, только ведь насколько "угробищьней" код будет выглядить.
А скопировать описание состояния? В массиве структур я сделаю memcpy (&state_copy, &state, sizeof(cond));
А в случае структуры массивов как ваш код будет выглядеть?
Вообщем если вы делаете "структуру массивов", то после этого выкидываете структуру, ничего при этом не потеряв и улучшив читаемость кода, и получаете просто "два массива". Что есть тоже вариант. О чем изначально и говорилось.
А как теперь узнать размерность?
Конструкция вида:
Не работает (
Псрото в делфе подобная вещь спокойно работает. Даже когда скажем я использую конструктор типа массив в массиве length всегда отрабатывает. А тут (
Сам же и отвечу на свой вопрос:
Первый раз получаем размер в байтах всего массива, а затем делим его на размер записи одного элемента. Очень удобно.