As a "still learning Arduino and C++" exercise I built a multi-player Simon Says game. It all works now. At one point I thought I needed to pass player data structures to functions that in turn passed them to other functions. Each function modifying the data in the original structure member. I could not get that to work and solved the problem with simpler structures and some extra global variables.
But I want to understand how to deal with passing structure array members to cascading functions. So I wrote the demo code below which works and does exactly what I was trying to achieve.
Problem is I do not understand why it works. In the call to the first function I need to pass the Struct array member parameter using dereference (&) and have the function receive it with a pointer argument. But when the first function calls the second one the structure member parameter is passed referentially with no * or & but is still received as a pointer argument. I understand that "by reference" and pointer mean the same thing (eg passing arrays), but I am confused here as the first function call requires the dereference - and it is a member of an array!.
So obviously I have stuff to learn but I have not been able to find clear explanation of this in the stuff available on line. Can someone explain this for me?
Also, is this a clumsy way of doing what I need. Is there a simpler way. I tried creating a series of structure types (redPlayer, GreenPlayer, etc) and then making an array of them, but got completely out of my depth - couldn't get the original copy of the data updated.
Any help much appreciated.
/*
* routine to demo passing a member of a struct array down through
* (two) cascading function calls. Summary:
*
* struct sName { };
* structArray sName sMember[] {
*
* pass array member from loop to first function
* with dereference "&"
*
* firstFunction(&structArray[n]);
*
* receive into first function as pointer "*"
*
* void firstFunction(structName *sMember)
*
* pass to second function plainly by reference only (is a pointer??)
*
* secondFunction(sMember);
*
* receive into second function with pointer
* void secondFunction(sName *sMember)
*
* in both functions access structure data with "->" not "."
*
* Both functions update the structure directly and don't make copies.
*
* Code below works
*/
enum colour {RED = 0, YELLOW = 1, GREEN = 2, BLUE = 3};
struct playerData
{
char pName[10]; //player's literal name
byte offset; //offset to player's button pins (colour)
byte pattern [5]; //pattern of random LED flashes player must remember
};
playerData player[] =
{
{"RED", RED, {1,1,1,1,1}},
{"YELLOW", YELLOW, {1,1,1,1,1}}
};
void setup()
{
Serial.begin(19200);
delay(200);
Serial.println();
}
void loop()
{
Serial.println("In loop original data before call to firstFunction. ");
printPlayerData(0);
Serial.println();
firstFunction(&player[0], 0); //Passes RED player data without call to 2nd function
Serial.println("In loop after first function data changed to ");
printPlayerData(0);
firstFunction(&player[0], 1); //Passes RED player data and request to call to 2nd function
Serial.println();
Serial.println("In loop after second function data changed to ");
printPlayerData(0);
while (true) {;}
}
void firstFunction(playerData *player, bool call)
{
if (!call)
{
player->offset = GREEN; //2
player->pattern[1] = BLUE; //3
}
else
{
secondFunction(player); //call to second function parameter is not pointer
}
}
void secondFunction(playerData *player)
{
player->offset = YELLOW; //1
for ( int i = 0; i < 5; i++)
{
player->pattern[i] = i;
}
}
void printPlayerData(byte index)
{
Serial.print("Player Name is ");
Serial.println(player[index].pName);
Serial.print("Player offset is ");
Serial.println(player[index].offset);
Serial.print("Player pattern is ");
for ( int i = 0; i < 5; i++)
{
Serial.print( player[index].pattern[i]);
}
Serial.println();
}
Edit
Here is the output.
In loop original data before call to firstFunction.
Player Name is RED
Player offset is 0
Player pattern is 11111
In loop after first function data changed to
Player Name is RED
Player offset is 2
Player pattern is 13111
In loop after second function data changed to
Player Name is RED
Player offset is 1
Player pattern is 01234