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

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! Jan 25 '20 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! Jan 25 '20 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)'. Jan 25 '20 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). Jan 25 '20 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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