-1

Here's what I'm doing:

const uint16_t LAYERS_RIGHT[TOTAL_LAYERS][NBROW][NBCOL] = {
  {{c00, c10, c20, c30, c40, c50, c60},
   {c01, c11, c21, c31, c41, c51, c61},
   {c02, c12, c22, c32, c42, c52, c62},
   {c03, c13, c23, c33, c43, c53, c63},
   {c04, c14, c24, c34, c44, c54, c64},
   {c05, c15, c25, c35, c45, c55, c65}}
   /* blah blah */
};
const uint16_t LAYERS_LEFT[TOTAL_LAYERS][NBROW][NBCOL] = {
   /* blah blah */
   /* blah blah */
};

uint16_t *(LAYERS[TOTAL_LAYERS][NBROW][NBCOL]);

My goal is try to make a pointer to that either right structure or left structure:

LAYERS = &LAYERS_RIGHT;

The compiler says:

error: incompatible types in assignment of 
'const uint16_t (*)[7][6][7] {aka const unsigned int (*)[7][6][7]}' to 
'uint16_t* [7][6][7]         {aka unsigned int* [7][6][7]}'

How to make my code work?

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
  • 1
    1) There is no structure. `LAYERS_*` are arrays. 2) Note: All-uppercase names should be used for macros and constants **only**. 3) Arduino is **not** C! 4) Please get a C++ beginner book. The snippets are completely wrong. 5) There is no code shown. – too honest for this site Sep 22 '16 at 16:34
  • 2
    The answer lies in the error. – 2501 Sep 22 '16 at 16:35
  • *Arduino is not C!* this is worth repeating. –  Sep 22 '16 at 16:37
  • 1
    @JarrodRoberson: There should an auto-comment if someone adds both tags. – too honest for this site Sep 22 '16 at 16:44
  • @Olaf I had almost the same reputation as yours a few months ago and I'm asking too many questions and not answering anymore that's why I'm only 6k now, but I really hope I've never done such cheeky answer. I'm a professional and I'm not *that* dumb. If I'm asking such question it's because (1) i'm programming a Teensy (2) it's C (not C++) you sound soo good you know the difference (3) I dont want to bother people with more than 300 lines repeating themselves (where I've put "`blabla`"). – Olivier Pons Sep 22 '16 at 19:25
  • I'm very sorry if I sound cheeky here, I'm just saying I'm not a beginner and if I ask this it's because there is a good reason, not like a student trying to pass an exam. – Olivier Pons Sep 22 '16 at 19:26
  • 1) I commented, did not answer 2) It is problematic to judge from your code if you are a pro or not. 3) It does not matter. Bad code is bad code. 4) As a pro, you really should know how to interpret compiler errors and be able to do some research. 5) if that is C, it is not arduino, but just AVR. I'd be fine if you change both tags. – too honest for this site Sep 22 '16 at 19:34
  • One click away to see my profile, it's not that far I guess. I've changed the tags I sincerely hope you're feeling better now **`<:^D`** – Olivier Pons Sep 22 '16 at 19:40

1 Answers1

1

You have LAYERS defined as a 3D array of pointers. You want a const pointer to a 3D array:

const uint16_t (*LAYERS)[TOTAL_LAYERS][NBROW][NBCOL];

To use this however, you need to use syntax like this:

(*LAYERS)[a][b][c];

If you want to index LAYERS as a 3D array, you can instead define it like this:

const uint16_t (*LAYERS)[NBROW][NBCOL];

And assign it like this:

LAYERS = LAYERS_RIGHT;

This takes advantage of the fact that in some contexts an array decays into a pointer to the first element. The above assignment is one of them.

LAYERS_RIGHT is an array of const uint16_t [NBROW][NBCOL], so the type of the address of one of these array elements is const uint16_t (*)[NBROW][NBCOL], which is the type of LAYERS.

Then LAYERS[0] references the first const uint16_t [NBROW][NBCOL], LAYERS[1], the second, and so forth.

So after the above assignments, this expression

LAYERS_RIGHT[a][b][c];

Yields the same value as this expression:

LAYERS[a][b][c];
dbush
  • 205,898
  • 23
  • 218
  • 273
  • A pointer to a 2D array would be the more "natural" type, as that is the same a 3D array parameter is converted to. – too honest for this site Sep 22 '16 at 18:52
  • I'd feel better if you made clear **why** that works. There is already too much confusion about pointers and arrays. – too honest for this site Sep 22 '16 at 18:57
  • I'd change "`LAYERS_RIGHT` is an array" to something like "an array with elements of type ..." or so. I first read it as if it was of that type. But it is well possible that is just my language skills and not being well concentrated. – too honest for this site Sep 22 '16 at 19:10
  • @dbush Thank you very much for being so nice, patient and altruist. **You** deserve your reputation. – Olivier Pons Sep 22 '16 at 19:31
  • @dbush I'm sorry to bother you, but I'm trying to make a function that can take the value of `Layers[0][0][0]` and I'm declaring it like this: `void ExecutePress(const uint16_t key)` and I get the compiler error: `note: initializing argument 1 of 'void ExecuteRelease(uint16_t)`... I dont know what I am missing. And as Olaf pointed out, I'm asking such silly questions because I'm actually running out of money and I have to make my project *before end of november* working otherwise I dont know what I will become... – Olivier Pons Sep 22 '16 at 20:01
  • 1
    @OlivierPons Please create a new question with all relevant details. – dbush Sep 22 '16 at 20:25