如何声明指向多维数组的指针数组

时间:2012-01-26 00:54:49

标签: c++ arrays pointers multidimensional-array

// 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[]的正确类型。

我想知道???应该是什么?

我正在使用微控制器并且必须使用数组以强制数组进入闪存而不是RAM。

4 个答案:

答案 0 :(得分:3)

你不能将数组转换为“指针指针......指针”,因为它们的取消引用方式不同;尝试使用多维数组作为“指向某个指针”的指针将导致未定义的行为,就像取消引用无效指针一样。

在内存中,对象的“指向指针...的指针”由

表示
a -> b -> c -> ... -> object

abc...object处于完全不同的记忆部分。要索引指针,指针将被解除引用。

然而,数组存储在连续的内存中。例如,int a[2][2]将是

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

对多维数组建立索引取消引用指针,它会更改用于计算所需值所在的数组开头的偏移量的算术运算。公式将是

  

数组的地址 + index 1 * sizeof(第一维)+ index 2 * sizeof(第二维)+ ... + index n * sizeof(object)

其中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,是数组的最后一个元素。

要解决此问题,您只需要使用指针。你不应该(也不能)将多维数组与指针放在同一个数组中。

<小时/> 我很难把这一切都写进去;如果我没有意义,请说出来。

答案 1 :(得分: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
};

答案 2 :(得分: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
};

如果某些阵列是固定长度的,可以稍微清理一些。

但IMO变得非常丑陋,可以使用一些真正的结构,而不是原始数组。

答案 3 :(得分: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
      ...
);