0

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!

enter image description here

2 Answers 2

1

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 );
1
  • 1
    Thanks. I mostly code in C# and in this case I had forgotten Array of structures looks different than managed world!
    – BHP
    Commented Jan 25, 2020 at 15:46
1

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);
3
  • 1
    Thanks! Coming from managed world, I forgot the pointers behavior!
    – BHP
    Commented 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)'. Commented 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). Commented Jan 25, 2020 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.