Массив из существующих массивов

У меня есть куча 3D-массивов в следующем виде:

byte lines[][4][2] {
                     { {B00000000, B11110000 }, 
                       {B00000000, B11110000 }, 
                       {B00000000, B11110000 }, 
                       {B00000000, B11110000 } },
                     { {B11110000, B00000111 }, 
                       {B00000000, B11111000 }, 
                       {B00000000, B11111000 }, 
                       {B00000000, B11111000 } },
// continues for numerous elements
                    }

Они представляют собой набор значений для передачи в пару регистров сдвига, управляющих светодиодной матрицей. Каждый массив, по сути, представляет собой анимацию, которая воспроизводится на светодиодной матрице.

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

Я хочу сделать что-то вроде этого

sometype* sequence[] = { lines, circles, squares } ;

или, если это невозможно, тогда:

sometype* sequence[3];
sometype[0] = lines;
sometype[1] = circles;
sometype[2] = squares;

Могу ли я сделать это или какое-то приближение к этому? Если да, то что такое "какой-то тип"? Я не могу понять, как сказать "массив указателей на массивы байтов 3d" или что бы я ни пытался сделать. Каков синтаксис для объявления массива и разыменования указателей?

, 👍0


2 ответа


0

Да, вы можете ( в обоих направлениях )

Тебе нужно

typedef byte sometype[4][2];

Однако вам, вероятно, понадобится размер линий, кругов и т. Д. , Который теряется указателем.

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

struct sometype {
  size_t n;
  byte [][4][2] data;
} lines ;

ИМО, даже 2D-массивы достигают пределов человеческого интеллекта, и я бы предпочел еще больше пользовательских типов:

typedef byte Pattern[4][2]; // or a more appropriate name

Pattern lineArray[] { 
             { {B00000000, B11110000 }, 
               {B00000000, B11110000 }, 
               {B00000000, B11110000 }, 
               {B00000000, B11110000 } }
          , { {B11110000, B00000111 }, 
               {B00000000, B11111000 }, 
               {B00000000, B11111000 }, 
               {B00000000, B11111000 } }
};

typedef struct { 
  size_t count;
  Pattern* data;
} PatternCollection; 

PatternCollection lines = {sizeof(lineArray)/sizeof(Pattern), lineArray };

PatternCollection sequence[] = {lines /* , circles, squares */ }; // if you ever need to iterate them 
,

1

Попробуйте это:

byte (*sequence[])[4][2] = { lines, circles, squares } ;

Пояснение: Идентификаторы линий, кругов и квадратов распадаются на указатели на первый элемент каждого массива. Их распадающиеся типы затем являются “указателем на массив длиной 4 массива длиной 2 байта”. Этот тип может быть объявлен как

typedef byte (*pointer_to_2d_array)[4][2];

Затем последовательность представляет собой массив этого типа, который может быть объявлен как

pointer_to_2d_array sequence[] = { ... };

или, если вы цените неясную элегантность синтаксиса C, как в начале этого ответа.

,