Passing arrays to class constructors

Hi folks. I am trying to pass an array to a class constructor but run into trouble when i try to assign them.
I have read that in C you cannot assign arrays and must use pointers instead. I have tried using the * operator and managed to compile my program but it doesn't work as it should.
If anyone could point out where I am going wrong that would be great. Thanks, Danny.

class Motion {//class to encapsulate the functionality required to play a motion
    byte *xMotion;//byte arrays
    byte *yMotion;
    byte s;//size of byte arrays

  public:
    Motion(byte xMotion_[], byte yMotion_[], byte s_) {//pass the arrays containing the x and y motions and the sizes thereof
      xMotion = xMotion_;
      yMotion = yMotion_;
      s = s_;
    }

gonadgranny:
Hi folks. I am trying to pass an array to a class constructor but run into trouble when i try to assign them.
I have read that in C you cannot assign arrays and must use pointers instead. I have tried using the * operator and managed to compile my program but it doesn't work as it should.
If anyone could point out where I am going wrong that would be great. Thanks, Danny.

class Motion {//class to encapsulate the functionality required to play a motion

byte *xMotion;//byte arrays
    byte *yMotion;
    byte s;//size of byte arrays

public:
    Motion(byte xMotion_[], byte yMotion_[], byte s_) {//pass the arrays containing the x and y motions and the sizes thereof
      xMotion = xMotion_;
      yMotion = yMotion_;
      s = s_;
    }

passing a pointer to the array which the class instance will be using is workable.

what is your problem, exactly? Perhaps create a member function that simply traverses and prints the values in your arrays, to make sure you are happy with the data.

(Remember that you can use pointer arithmetic to traverse arrays.)

Example:

class Motion {
    byte *xMotion;//byte arrays
    byte s;//size of byte arrays

  public:
    Motion(byte xMotion_[], byte s_){xMotion = xMotion_; s = s_;};
    void printArray(){byte* ptr = xMotion; for(int i = 0; i < s; i++) {Serial.println(*ptr++);}};
};

byte myArray[] = { 255, 0, 125, 0, 255};

Motion motion(myArray, sizeof(myArray)/sizeof(myArray[0]));

void setup() 
{
  Serial.begin(9600);
  motion.printArray();
}

void loop() 
{

}

(I still think you would be happier putting those two arrays into a struct that contained the x and y positions :wink: )

Edit: like this:

struct Data{
  byte x;
  byte y;
};

class Motion {
    Data *xMotion;//byte arrays
    byte s;//size of byte arrays

  public:
    Motion(Data xMotion_[], byte s_){xMotion = xMotion_; s = s_;};
    void printArray(){
      Data* ptr = xMotion; 
      for(int i = 0; i < s; i++) 
      {
        Serial.print(ptr->x);
        Serial.print(",");
        Serial.println(ptr++->y); //looks weird, right?!
        //Serial.println(ptr->y); // alternate approach for readability
        //ptr++
      }
    };
};

Data data[] = { 
  {255,   0},
  {125, 255}, 
  {255, 125}
};

Motion motion(data, sizeof(data)/sizeof(data[0]));

void setup() 
{
  Serial.begin(9600);
  motion.printArray();
}

void loop() 
{
}
1 Like

Thanks for that. I needed to be sure that the code was correct and in fact it was but i had taken out a piece of code to simplify it which inverted the values causing me to think that the servo was being fed the wrong data when it just needed to be inverted. then i tried to print it but.....i wont bore you with the details, i works! many thanks. As for the structs, i am interested in these. anything which can organise my data better is worth a look. is a struct a little bit like a vector in other languages?

gonadgranny:
is a struct a little bit like a vector in other languages?

it is an object, similar to a class .

Differences between a class and a struct in C++ are that structs have default public members and bases and classes have default private members and bases. Both classes and structs can have a mixture of public and private members, can use inheritance and can have member functions...

... recommend using structs as plain-old-data structures without any class-like features, and using classes as aggregate data structures with private data and member functions.

So, like JavaScript objects, structs can contain different data types and functions.

C++ also has vectors, not supported on arduino.

gonadgranny:
anything which can organise my data better is worth a look

it seems to me more manageable (i.e. editable) in sets, especially once it sits in your code.

Gotcha. since i need to store 2 arrays would it not be?:

struct Data{
  byte x[];
  byte y[];
};

How does one define arrays within the struct format? if this is for non array data:

Data data0 = { 255 , 0 , 0 };

for an array would be? :

Data data0 = { {255 , 0 , 0},{255,0,0} };

gonadgranny:
Gotcha. since i need to store 2 arrays would it not be?:

struct Data{

byte x[];
  byte y[];
};

No, like I showed you.

struct Data{
  byte x;
  byte y;
};

You will then create an array of that object:

Data myData[] = { 
//   x,   y
  {255,   0},
  {125, 255}, 
  {255, 125}
};

you then access the elements with the dot operator (like other languages)

int thisElement = myData[0].x;  // this =255

int thatElement = myData[2].y;  // that =125

Thanks for that. I'll implement that next.
I am still having trouble with my class at the moment. i get this error:

'motionArr' was not declared in this scope

when i try and run this code:

class Sequence {
  byte *sequence; //array to hold the indexes of the motions
  int *timings; //array to hold the timinngs between the motions
  byte s; //byte to hold the size of the array
  boolean once = true;
  
  public:
  Sequence(byte sequence_[],int timings_[], byte s_){
    sequence = sequence_;
    timings = timings_;
    s = s_;
  }
  

  void play(){
    if(once == true){ //declare the array just once
       Motion motionArr[2] = { Motion(xMotion01, yMotion01,sizeof(xMotion01S)),Motion(xMotion02, yMotion02,sizeof(xMotion02S))};
       once = false;
    }
    for(int i = 0; i < s ; i++){//cycle through each motion
      motionArr[i].play(); //use the value from the sequence list to choose the index of the motions list
      delay(timings[i]);//this is the 
    }
  }
};

Could anyone enlighten me on how to increase the scope? In processing(java) i would declare motionArr outside of the function as in : Motion motionArr; but this doesn't work. Any thoughts? Thanks, Danny.

    if(once == true){ //declare the array just once
       Motion motionArr[2] = { Motion(xMotion01, yMotion01,sizeof(xMotion01S)),Motion(xMotion02, yMotion02,sizeof(xMotion02S))};
       once = false;
    }

motionArr has block scope... it was created in that block and is destroyed once that block in finished.

More on Scope Here

Another approach would be to create a global pointer to an int object, then when you want to change what you "Play Back" you just move the pointer to another array...

int myArrayA = {...  // a global array
int myArrayB = {...  // another global array

int* currentArray = myArrayA;  // pointer to an int of Global Scope initialized to point to myArrayA

void loop(void)
{
  if(something)
    currentArray = myArrayB;  //pointer now points to myArrayB
  // and so on...

thing is, you need the size if they are different... introduce yourself to Mr. struct, again!

struct SomeArrayData{
  int* array;
  size_t size;
};

if you haven't noticed, what you are doing isn't beginner level stuff, so good for you!

Thanks very much for this, you've been of great help. It looks like my 'homework' for the weekend is to familiarise myself with structs and pointers then!

Another approach would be to create a global pointer to an int object

Might i ask why you changed the data type from byte to Int here?
Also, when declaring my struct arrays, i was wondering if there was any other syntax i could use other than the one you demonstrated. for example rather than {x,y}{x,y}{x,y} i would like {x,x,x,}{y,y,y} it would just make life easier for me to put the lists of number together...
Thanks. Danny.

a struct can contain an array, if you want to do it that way. A bit harder to manage sets like that but sure:

struct MyStruct{
  byte x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  byte y[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
}myStruct;

access them similarly:

byte someByte = myStruct.y[3];  // = 6

my example were ints, but you can use any data type.