Printing structure variables, I get default values. What is wrong with my code?
struct SCENARIO
{
int Lamp_Pin = -1;
int PB_Pin = -1;
} ;
SCENARIO _red;
SCENARIO _yellow;
SCENARIO _white;
SCENARIO _stop;
SCENARIO btns[4] = { _red, _yellow, _white, _stop};
void setup()
{
_stop.Lamp_Pin = 8;
_stop.PB_Pin = 4;
///// initializing other 3 objects i.e. red & white & yellow
////
for (int i = 0; i < 4; i++)
{
Serial.print(i);Serial.print(":");
Serial.print(btns[i].Lamp_Pin);Serial.print(":");
Serial.println( btns[i].PB_Pin );
//pinMode( btns[i].Lamp_Pin, OUTPUT);
//pinMode( btns[i].PB_Pin, INPUT);
}
}
The image below shows what I get. It seems I have not initialized the variables!
2 Answers 2
In this line:
SCENARIO btns[4] = { _red, _yellow, _white, _stop};
you are making 4 copies of the structures and placing them in an array.
Instead you should either create the array directly with the values:
SCENARIO btns[4] = {
{-1, -1},
{-1, -1},
{-1, -1},
{8, 4}
};
And only use the array, or use pointers in the array:
SCENARIO *btns[4] = { &_red, &_yellow, &_white, &_stop };
and then access the entries as pointers:
Serial.print(btns[i]->Lamp_Pin);
Serial.print(":");
Serial.println( btns[i]->PB_Pin );
-
1Thanks. I mostly code in C# and in this case I had forgotten Array of structures looks different than managed world!BHP– BHP2020年01月25日 15:46:33 +00:00Commented Jan 25, 2020 at 15:46
The problem is that a struct is handled as a value type, not as a reference type.
This means that a copy of _stop
is made and put in btns
(btns[3]
actually).
So what you need to do is putting pointers into the btns
array:
SCENARIO* btns[4] = { &_red, &_yellow, &_white, &_stop};
The symbol * denotes a pointer, and & means the address of a variable (so it points to the variable and is not a copy).
Now when you change _stop
, also btns[3]
which points to _stop
will show the correct initialized value.
For printing you should use:
Serial.println( (*btns[i]).LampPin);Serial.print(":");
Serial.println( (*btns[i]).PB_Pin );
Because *btns[i] is a pointer, but because this is a very often used feature, a special notation can be used:
Serial.print(btns[i]->Lamp_Pin);Serial.print(":");
Serial.println( btns[i]->PB_Pin);
-
1Thanks! Coming from managed world, I forgot the pointers behavior!BHP– BHP2020年01月25日 15:44:55 +00:00Commented Jan 25, 2020 at 15:44
-
@BehzadSedighzadeh Luckily in C# they don't exist anymore, but with programming lower level devices, you don't want to rely mostly on automatic memory allocation and garbage collection and pointers are 'directly to the point(er)'.Michel Keijzers– Michel Keijzers2020年01月25日 15:54:36 +00:00Commented Jan 25, 2020 at 15:54
-
If an answers helped you, upvote it (arrow next to the question), for the best answer, accept the answer (under the arrows next to a question).Michel Keijzers– Michel Keijzers2020年01月25日 16:33:42 +00:00Commented Jan 25, 2020 at 16:33