2012-01-26 3 views
0
// LED definitions for each step 
static uint8_t route1Step0LedsOn[] = { 0x30, 0xff }; 
static uint8_t route1Step0LedsOff[] = { 0x26, 0xff }; 
static uint8_t route1Step1LedsOn[] = { 0x18, 0x45, 0x21, 0xff }; 
static uint8_t route1Step2LedsOn[] = { 0x56, 0x33, 0x42, 0x31, 0xff }; 

// First route (consisting of 3 steps + terminator). 
static uint8_t* routeLeds1[][2] = 
{ 
    { route1Step0LedsOff, route1Step0LedsOn }, 
    { NULL,    route1Step0LedsOn }, 
    { NULL,    route1Step0LedsOn }, 
    { NULL,    NULL } 
}; 

// Second route. 
static uint8_t* routeLeds2[][2] = 
{ 
    // LED elements not shown, but similar to route 1. 
    { NULL,    NULL } 
}; 

// Array of routes. 
static ??? routes[] = 
{ 
    NULL, 
    routeLeds1, 
    routeLeds2, 
    NULL 
}; 

Я не уверен в правильном типе для routes[].Как объявить массив указателей на многомерные массивы

Я хотел бы знать, что должно быть ????

Я использую микроконтроллер и ДОЛЖЕН использовать массивы, чтобы заставить массивы во флэш-памяти вместо ОЗУ.

+0

, что в мире, вы пытаетесь сделать? – Anycorn

+0

Редактированное сообщение. Помогает ли это? – sixeyes

+0

рассмотрите возможность использования boost multi_array. – Anycorn

ответ

1

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

typedef uint8* Array1; // first column/row 
typedef Array1 Array2[2]; // uint* name[2] 
typedef Array2* Array3; // get the idea? 

// Array of routes. 
static Array3 routes[] = 
{ 
    NULL, 
    routeLeds1, 
    routeLeds2, 
    NULL 
}; 
+0

Работает лечения. Спасибо за ответ. – sixeyes

3

Вы не можете преобразовать массивы в «указатели на указатели ... на указатели», потому что они разыменованы по-разному; попытка использовать многомерный массив как «указатель на ... указатель» на что-то приведет к неопределенному поведению так же, как разыменование недопустимого указателя.

В памяти, «указатель на указатель ...» на объект представлен

a -> b -> c -> ... -> object 

Где a, b, c, ... и object находятся в совершенно разных частях памяти. Чтобы индексировать указатель, указатель разыменовывается.

Массивы, однако, хранятся в непрерывной памяти. Например, int a[2][2] бы

[0,0][0,1][1,0][1,1] 

Индексирования многомерного массива делает не разыменовать указатель, он изменяет арифметику, который используется для вычисления смещения от начала массива, что требуемое значение в. Формула будет

адрес массив + индекс * SizeOf (первое измерение) + индекс * SizeOf (второе измерение) + ... + указательного п * SizeOf (объект)

Место, где sizeof(nth dimension) - размер всех подмножеств, составленных вместе. Например, с int a[3][2] который представлен

[0,0][0,1][1,0][1,1][2,0][2,1] 

, индекс a[2][1] будет

адрес a + 2 * (SizeOf (INT) * 2) + 1 * SizeOf (INT)

Какой, на C++, будет (char*)a + 16 + 4, последний элемент массива.

Для решения этой проблемы вам необходимо использовать указатели. Вы не должны (и не можете) хранить многомерные массивы рядом с указателями в одном массиве.


Мне сложно вложить все это в слова; если я не имею смысла, скажите об этом.

+0

Я не уверен, что мое намерение было ясным. Я редактировал свой оригинальный пост. Мне интересно иметь массив маршрутов, но объявить, что это проблема. Код размещен работает, но является уродливым. Я уверен, что есть способ очистить синтаксис. – sixeyes

+0

@sixeyes by «work», вы имеете в виду, что он компилируется, или он запускается (и «маршруты» используются в активном коде)? –

+0

Запуск. Когда я печатаю, светодиоды мигают правильно. – sixeyes

0

Ваша проблема заключается в многомерный массив:

Если вам нужно идти по пути массива, вы можете просто добавить дополнительный шаг:

static uint8_t route1Step0LedsOn[] = { 0x30, 0xff }; 
static uint8_t* route1Step0[] = { NULL, route1Step0LedsOn }; 
static uint8_t** routeLeds1[] = { route1Step0 }; 
static uint8_t*** routes[] = 
{ 
    NULL, 
    routeLeds1, 
    NULL 
}; 

Если некоторые из массивов фиксированной длины, это возможно, немного почистить некоторые из них.

Но ИМО это становится довольно уродливым и может иметь дело с некоторыми реальными структурами, а не с необработанными массивами.

+0

Вот как я изначально написал его, но его было сложнее поддерживать. К сожалению, ни один из массивов не фиксируется по длине. – sixeyes

+0

Я использую микроконтроллер, и используя structs будет использовать оперативную память, тогда как текущая форма целиком находится во флэш-памяти. – sixeyes

+0

@sixeyes вы уверены, что используя structs будет использовать RAM? Является ли это специфическим для компилятора C++ используемого вами микроконтроллера? –

0

Если вы не привязаны к массивам ussing по какой-либо технической причине, вы можете изменить их на использование такой структуры: (Обратите внимание, что если вы используете C++ 11, то конструкторы и конструкция могут быть сделаны много лучше). Вам также понадобится помощник make_vector, из которого несколько плавающих вокруг, если вы хотите более красивую конструкцию.

struct LedList 
{ 
    LedList(const std::vector<uint8_t> & v) : leds(v) {} 
    std::vector<uint8_t> leds; 
}; 

struct LedStep 
{ 
    LedStep(const & LedList on_, const & LedList off_) : on_leds(on_), off_leds(off_) {} 
    RouteStepLedList on_leds; 
    RouteStepLedList off_leds; 
}; 

struct LedRoute 
{ 
    LedRoute(const std::vector<LedStep> & steps_) : steps(steps_) {} 
    std::vector<LedStep> steps; 
}; 

struct Route 
{ 
    Route(const std::vector<LedRoute> & routes_) : routes(routes_) {} 
    std::vector<LedRoute> routes; 
}; 

//All routes 
Route r(make_vector<LedRoute>()( 
    //First route 
    make_vector<LedStep>()(
     //First step of first route 
     LedStep( 
     make_vector<uint8_t>()(0x30), 
     make_vector<uint8_t>()(0x26) 
    ))(
     //Second step of first route 
     LedStep(
     make_vector<uint8_t>(), 
     make_vector<uint8_t>()(0x18)(0x45)(0x21) 
    ))(
     //Third step of first route 
     LedStep(
     make_vector<uint8_t>(), 
     make_vector<uint8_t>()(0x56)(0x33)(0x42)(0x31 ) 
    ))), 
    //Second route. 
    make_vector<LedStep>()(
     //First step of second route 
     LedStep( 
     ... 
     )) (
     //Second step of second route 
     ... 
); 
+0

К сожалению, нет STL, и я привязан к использованию массивов, чтобы держать их во флеше. На самом деле я должен использовать дополнительные ключевые слова в фактическом коде для размещения массивов во флэш-памяти. – sixeyes

Смежные вопросы