Как сделать массив в массиве (вложенный массив)?

Draghkon
Offline
Зарегистрирован: 17.09.2013

Здравия всем. Вопрос может нубский. Но такая уж задача - и мне видится что такое решение было бы самым элегантным.

тогда должно выйти примерно так: 

int Tasks [2][24]; //тут все просто - это массив самих действий - 1 колонка параметр, 2- значение и всего 24 строки.

а вот дальше - нужно создать массив, каждая ячейка которого будет содержать экземпляр массива Tasks а количество этих ячеек желательно тоже неограничено. но для примера укажу  255.

Попробовал так:

int Meta_Tasks [Tasks][255]; 

//и нужно создать еще один уровень:

int Global [Meta_tasks][1024];

 

В таком виде компилятор это кушать не хочет.

Пробовал сделать в таком виде:

int Tasks[24][2];
int Meta_tasks[Tasks[24][2]][255];
int Global[Meta_tasks[Tasks[24][2]][255]][1024];

ошибки пропали, но выводятся предупреждения "array subscript is above array bounds" что как бы намекает что работать так как надо моя конструкция не будет...

Вопрос - можно ли такую конструкцию реализовать в ардуино, и если да, то как?

Draghkon
Offline
Зарегистрирован: 17.09.2013

Щас перечитал еще раз.. и понял что я делаю что-то не то...

Вобщем попробую описать что мне нужно на примере с деревом файлов:

есть список папок (массив первого уровня), которые имеют имена (числовые значения int) - мне нужно чтобы при считывании определенного имени папки в переменную она открывалась и я получал доступ к содержащимся в этой папке файлам (массив второго уровня) - каждый из которых также имеет имя (значение int) и открыв файл с нужным именем я получал бы доступ к таблице из 2х столбцов (двумерный массив 3-го уровня) - в котором уже содержатся необходимые мне значения и параметры.

Т.о. я имею нужные мне значения и их адрес (который складывается из значении содержащих их массивов 2 и 1 уровня).

Вот как это реализовать поудобнее  .. что то клинит.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Draghkon пишет:

i
int Tasks[24][2];
int Meta_tasks[Tasks[24][2]][255];
int Global[Meta_tasks[Tasks[24][2]][255]][1024];

ошибки пропали, но выводятся предупреждения "array subscript is above array bounds" что как бы намекает что работать так как надо моя конструкция не будет...

Вопрос - можно ли такую конструкцию реализовать в ардуино, и если да, то как?

Ответ  отрицательный

array subscript is above array bounds  индекс массива находится выше границы массива

Первый массив занимает 24 х 2 = 48 байт

Второй-  24 х 2 х 255 =  12240 байт

Третий-  12533760   ....  а это  12 с половиной  МегаБайт

Если очень нужно создать массив такого размера-  создавайте где-нибудь в другом месте но не на Атмелевских 8-ми битных процессорах.

Draghkon
Offline
Зарегистрирован: 17.09.2013

Ну если так, то больше - ведь в в значениях хранятся данные не по 1 байту (до 255) а побольше скажем числа такие как 44976.

Тогда давайте с другой стороны подойдем - мне нужно хранить в памяти одновременно только данные из последнего массива т.е. 2х24 + 2 значения массивов в которых хранится этот массив.

т.е. можно ли как то нпример не тратить память на весь объем сразу, а например получить список значений из массива верхнего уровня (1024), найти нужное, сохранить в переменную и выгрузить все остальные из памяти - потом получить список занчений из этого найденного массива второго уровня (255) - найти нужное, сохранить его в переменную и выгрузить остальные. и наконец получить массив значений третьего уровня 2х24. С ними уже ведется дальнейшая работа... затем, когда понадобятся эти 2х24 значения из другого адреса - производим чтение заново. 

т.е. чтобы не загружать в память весь этот свернутый массив разом. Можно ли так?

Вообще данные содержатся во внешнем файле базе данных. т.е. планировалось всю бд загружать в виде трехэтажного массива и потом в программе уже получать нужные данные отсеивая лишнее. Хотя может есть и другой путь наверняка.

maksim
Offline
Зарегистрирован: 12.02.2012

trembo пишет:

Draghkon пишет:

i
int Tasks[24][2];
int Meta_tasks[Tasks[24][2]][255];
int Global[Meta_tasks[Tasks[24][2]][255]][1024];

ошибки пропали, но выводятся предупреждения "array subscript is above array bounds" что как бы намекает что работать так как надо моя конструкция не будет...

Вопрос - можно ли такую конструкцию реализовать в ардуино, и если да, то как?

Ответ  отрицательный

array subscript is above array bounds  индекс массива находится выше границы массива

Первый массив занимает 24 х 2 = 48 байт

Второй-  24 х 2 х 255 =  12240 байт

Третий-  12533760   ....  а это  12 с половиной  МегаБайт

Если очень нужно создать массив такого размера-  создавайте где-нибудь в другом месте но не на Атмелевских 8-ми битных процессорах.

И еще все результаты умножайте на 2 , так как массивы типа int.

maksim
Offline
Зарегистрирован: 12.02.2012

Если данные статичны, то http://arduino.cc/en/Reference/PROGMEM

mixail844
Offline
Зарегистрирован: 30.04.2012

Двух мерный массив указателей,хранить на внешней памяти.

 int *Arr[X][Y]; 

Где X,Y -размеры массивов двух первых уровней.размер массива 3-го уровня указывать динамически.

leshak
Offline
Зарегистрирован: 29.09.2011

Может ошибаюсь, но помоему вы запутались в трех соснах.

Вы же уже смогли перейти от одномерного массива к многомерному. Уже сделали "массив в массиве". Двумерный - это частный случай многомерного. Переход к трехмерному не требуется поиска новых синтаксических конструкций. Полностью по аналогии.

int meta_tasks[255][2][24];

P.S. Но, конечно, это только с "точки зрения языка". Ограничение "объем памяти - не резиновый" это не отменяет.

Draghkon
Offline
Зарегистрирован: 17.09.2013

Спасибо - попробовал такую конструкцию - никаких ошибок нет...

Правда если сделать четырехмерный (хотябы 255)

int Massive [255][255][2][24];

то уже ругается, что массив слишком большой. - может быть получится обойти это способом, указанным maksim

 

Вообще я изначально делал эти конструкции, в надежде упростить доступ к содержимому, но впринципе сойдет и так. 

Осталось сделать массивы первого и второго уровня динамической длинны. Массив 3-го уровня всегда статичного размера.

Draghkon
Offline
Зарегистрирован: 17.09.2013

Да, сейчас подумал еще, и вспомнил почему я не хотел использовать такую конструкцию

int Massive [1024][255][2][24];

Дело в том, что чтобы добраться до нужных значений в массиве 3-го уровня, мне нужо знать индексы массивов 1 и второго уровня. Но проблема в том, что там нумерация не сквозная (1-255), а по датам и временным интервалам...

т.е. что-то вроде:

 20130723 (23 июля 2013г) - 46740 (12ч 59м 40с) - тут следуют данные из массива 3-го уровня.(2х24)

 20130916(16сент. 2013г) - 72000 (20ч 00м 00с) - тут следуют данные из массива 3-го уровня (2х24)

Вот как бы блин это увязать?  не делать же массив размером [21001231][86400][2][24]!!

Draghkon
Offline
Зарегистрирован: 17.09.2013

На ум приходит только делать 3 массива: 2 1мерных и 1трехмерный

Соотвтественно делать как-то так:





















int array_big[1024];
int big;
int index_big;
int array_middle[255];
int middle;
int index_middle;
int ArrayMain[1024][255][2][24];
int znach;
int param;

for (int i=0; i==1023; i++){
big=array_big[i];



//здесь идет проверка то ли значение нам нужно
if (big==/*нужному значению*/){
index_big=i;
break;
}
}

for (int i=0; i==254; i++){
big=array_middle[i];
//здесь идет проверка то ли значение нам нужно
if (middle==*/нужному значению/*){
index_middle=i;
break;
}
}

//а теперь уже можем достать нужное из трехмерного массива
for (int i=0; i==23; i++) {
znach=ArrayMain[index_big][index_middle][1][i];
//и присваиваем znach нужным переменным или что то еще делаем..
param=ArrayMain[index_big][index_middle][2][i];
//присваиваем параметры и т.п.
}

Но тут сильно много лишних переменных вылазиет..  Может есть способ компактнее?

leshak
Offline
Зарегистрирован: 29.09.2011

Ну, если у вас в качестве "ключа" испольуются даты, то вам в любом случае нужно будет вначале искать нужный индекс, а потом его использовать (что вы вообще-то выше и сделали). Если даты предварительно отсортированны, то можно занятся оптимизацией поиска. Бинарный поиск там и т.п (но очень под вопросом даст ли это ощутимый выигрышь на таком небольшом количестве данных).

Можно конечно попытатся минимизировать ваш когд. Вот эти for-ры поиски можно было и в отдельную функцию вынести, что-то типа 

index_big=findIndex(array_big,sizeof(array_big)/sizeof(int), /*НУЖНОЕ ЗНАЧЕНИЕ*/);
index_middle=findIndex(array_middle,sizeof(array_middle)/sizeof(int),*НУЖНОЕ ЗНАЧЕНИЕ2*/);

if(index_big!=-1 && index_middle!=-1){ // убеждаемся что смогли найти индексы
   .... достаем из массива многомерного.....
}


.....
где-то в низу

// ищет значение lookupValue в массиве arr размером arr_size
int findIndex(int arr[],unsigned int arr_size, int lookupValue){
  for(unsigned int i=0;i<arr_size;i++){
     if(arr[i]==lookupValue)return i;
  }
  
  return -1;// ничего не нашли
}

Ну либо сделать массив структур. struct (C programming language) - Wikipedia, the free encyclopedia