Refer to a STRUCT with a variable

I have 8 defined structures that are named the same with just an incrementing number on the end (i.e., label1, label2 …). I have a routine that gives me an int 1-8. Is there a way to refer to the individual structure using that int value?

This screams “use an array”.

Instead of

my_struct_t object1;
my_struct_t object2;
my_struct_t object3;
//..
my_struct_t object8;

Refactor to →

// Array of 8 such structs
my_struct_t objects[8];

So that you can do this

//access with
my_struct_t* pStruct = &objects[some_index_i];
pStruct->some_value = 123;
// or directly
objects[some_index_index_i].some_value = 123;

Otherwise you are forced to do unholy things

my_struct_t* pStructs[8] = {
   &object1, &object2, &object3, &object4, 
   &object5, &object6, &object7, &object8
};
my_struct_t* pStruct = pStructs[some_index_i];

I should have mentioned that the structures are created by a Squareline Studio project for the GUI. I don’t create the structures.

I see. If you want a mapping from int to your struct then, you would need either the pointer array per above or a mapping function (switch(the_index) { case 0: return &label1; case 1: return &label2; ..}.

Not at runtime, no.

Why not use an array of structs?

#include <Arduino.h>

typedef struct fred {
	int wilma;
	int bambam;
} fred_t;


fred_t stuff[] = {
	    {0,0},
	    {1,1},
            {2,2},
	    {3,3},
	    {4,4},
	    {5,5},
	    {6,6},
	    {7,7}
    };

const uint8_t LIMIT = sizeof(stuff)/sizeof(stuff[0]);


void setup() {
	Serial.begin(9600);
	for (byte x = 0; x < LIMIT; x++) {
	    Serial.print(x);
	    Serial.print(": ");
	    Serial.print(stuff[x].wilma);
	    Serial.print(',');
	    Serial.println(stuff[x].bambam);
	}
}

void loop() {
}

Running this, and opening the device monitor, gives:

0: 0,0
1: 1,1
2: 2,2
3: 3,3
4: 4,4
5: 5,5
6: 6,6
7: 7,7

So, you can do something similar i your code, get rid of the numeric suffixes, and choose your structure at will.

HTH.

Cheers,
Norm.

@maxgerhardt beats me to it yet again! :wink:

Cheers,
Norm.

Using switch does work, I was just trying to reduce my code. I tried the pointer array but it throws errors:

src/main.cpp:87:130: error: cannot convert ‘lv_obj_t**’ {aka ‘_lv_obj_t**’} to ‘lv_obj_t*’ {aka ‘_lv_obj_t*’} in initialization
lv_obj_t* medLbl[8] = { &ui_lblMed1, &ui_lblMed2, &ui_lblMed3, &ui_lblMed4, &ui_lblMed5, &ui_lblMed6, &ui_lblMed7, &ui_lblMed8};

Your ui_lblMed1 etc. variables are already lb_obj_t* so you don’t need the & in the array initialization. You’ll be copying the pointer’s value, aka the address they point at, which should be fine.

lv_obj_t* medLbl[8] = { ui_lblMed1, ui_lblMed2, ui_lblMed3, ui_lblMed4, ui_lblMed5, ui_lblMed6, ui_lblMed7, ui_lblMed8};

I’m still rather new to c++ and I still don’t have a good handle on pointers. Taking out the & works and will allow my code to be cleaner!

Thank you Max!
Bill

1 Like

Instead of experimenting with C++ if you don’t have much experience, I strongly suggest to start with plain C language, and read The C programming Language - Brian Kernighan and Denis Ritchie. Any ancient free download Visual Studio suite such as VS 2012 or VS Express, will be a perfect aid for your coding.

Your problem is a nice, basic example of an array of struct, simply indexed by an int (a single number). Unless something more complicated required, no pointers are needed.

Cheers