1

There are a bunch of questions like this here, I can't quite fine the right one to nail this - am hoping for a clearer answer (eg. Array of pointers to arrays is close, I just can't make it work with the typedef).

This code defines a set of animation sequences for a set of LEDs. The value(s) to be output are chosen based on the sequence, model of hardware and stage in the sequence. I am tempted to repeat the for loops for each sequence but I'll probably use this again and might learn something here too.

Based on printing the values, I don't get what I expect from *(sequences[mode])[model][prevstage][ix]. What am I missing?

void sequence(unsigned char reset, t_mode mode, unsigned char delaydiv4)
{
  typedef signed char seq_t[2][8][10];

  const seq_t centreSequence = {
    {
      {ZERO_LEFT_2, ZERO_RIGHT_2, -1},
.
      {-1},
    },
    {
      {ONE_LEFT_2, ONE_RIGHT_2, -1},
.
      {-1},
    },
  };
  const seq_t leftSequence  = {
    {
      {ZERO_RIGHT_2, -1},
.
      {ZERO_LEFT_TOP, ZERO_LEFT_BOT, -1},
    },
    {
      {ONE_RIGHT_2, -1},
.

      {ONE_LEFT_TOP, ONE_LEFT_BOT, -1},
    },
  };
  const seq_t rightSequence = {
    {
      {ZERO_RIGHT_2, -1},
.
.
      {ZERO_LEFT_TOP, ZERO_LEFT_BOT, -1},
    },
    {
      {ONE_RIGHT_2, -1},
.
.

      {ONE_LEFT_TOP, ONE_LEFT_BOT, -1},
    },
  };

  const seq_t* sequences[] = {&leftSequence, &rightSequence, &centreSequence};

  static unsigned char stage;
  static unsigned char prevstage; 
  const unsigned char model = 0;
  if (reset != 0)
    {
      stage = 1;
      prevstage = 0; 
    }

  for (unsigned ix=0; sequences[mode][model][prevstage][ix] != -1; ++ix)
    {
      digitalWrite(*(sequences[mode])[model][prevstage][ix], 0);
    }
Community
  • 1
  • 1
TomKeddie
  • 305
  • 1
  • 2
  • 10

2 Answers2

2

seq_t[2][8][10] is a 3D array. it means that seq_t is a pointer to pointer to pointer to typdef signed char . seq_t is pointing to the first place of a pointer array named seq_t[2] (an array of 2 pointers).

for a simple example just look at this picture :

enter image description here

its about a 2D array named nums[5][4] which nums[2] is an array of pointers to first place of each red array's and nums is a pointer to pointer to int(or whatever nums[5][4] is ...)

in your question &leftSequence is a pointer to leftSequence. the leftSequence itself is a pointer to pointer to pointer to char so you just build a pointer to pointer to pointer to pointer to char!!!!!

what do you really want to do with that?!!


I want to complete my answer.

in your code you wrote :

sequences[mode][model][prevstage][ix]   //in the while

and :

*(sequences[mode])[model][prevstage][ix]   //in digitalWrite

both are incorrect. * is a very low priority Operator so your 2nd code is exactly like :

*(sequences[mode][model][prevstage][ix])

as i said sequences[mode] is a pointer to one your three modes not one of them.

you can use () and * to fix both of them :

(*sequences[mode])[model][prevstage][ix]  

and at the end... you used an extra pointer. this is more simple :

  const seq_t* sequences[] = {leftSequence, rightSequence, centreSequence};

  sequences[mode][model][prevstage][ix] != -1               //in the while

  digitalWrite(sequences[mode][model][prevstage][ix], 0);   //digitalWrite

BTW i don't know much about digitalwrite function so maybe you need another * there ...

I think i explained it completely ...

amfad33
  • 74
  • 8
  • 1
    @GrijeshChauhan paint :D vary fast and free!! – amfad33 Jan 07 '14 at 06:14
  • Awesome thanks so much. So it was simple precedence in the end, thanks so much for taking the time to make such a complete answer. BTW I you can't drop the deference from the array element initialisers, I get `traffic_arrow.ino:125: error: cannot convert 'const signed char (*)[9][10]' to 'const signed char (*)[2][9][10]' in initialization` – TomKeddie Jan 07 '14 at 13:21
  • BTW, this is what the code is doing http://www.youtube.com/watch?v=YXkdf_tN8Vk - is for my kid's room. – TomKeddie Jan 07 '14 at 13:31
  • How nice! :) BTW i realy dont know much about digitalwrite function. maybe you need another * there – amfad33 Jan 07 '14 at 14:25
1

I have tested your code for a afternoon(I'm new to C),you can get what you want if you change

*(sequences[mode])[model][prevstage][ix]

to

(*sequences[mode])[model][prevstage][ix]

here is my code:

#include <stdio.h>
#include <stdlib.h>

typedef int seq_t[2][2][3];

const seq_t centreSequence = {
    {
      {1,2,3},
      {4,5,6},
    },
    {
      {7,8,9},
      {10,11,12},
    }
};

const seq_t leftSequence  = {
    {
      {13,14,15},
      {16,17,18},
    },
    {
      {19,20,21},
      {22,23,24},
    }
};

const seq_t rightSequence = {
    {
        {25,26,27},
        {28,29,30},
    },
    {
        {31,32,33},
        {34,35,36},
    }
};

int main(void)
{
    int j  = 0 , i1 = 0 , i2  = 0 , i3 = 0 ;

    const seq_t* sequences[] = {&centreSequence,&leftSequence, &rightSequence };

    for( j = 0 ; j < 3 ; j++ )
    {
        for( i1 = 0 ; i1 < 2 ; i1++ )
        {
            for( i2 = 0 ; i2 < 2 ; i2++ )
            {
                for( i3 = 0 ; i3 < 3 ; i3++ )
                {
                    printf("%d ",(*sequences[j])[i1][i2][i3]);
                }
                printf("\n");
            }
            printf("\n");
        }
        printf("\n");
    }
}
Nibnat
  • 119
  • 7