Reference Array - add a sub topic for handling arrays

Hello,

I recently started using an arduino and started using arrays. To quickly switch between certain states I defined array constants and wanted to assign those constants to a working array:

const byte i_face[8] = { // define a bit picture as a constant
 B01000010,
 ...
}
byte matrix [8] ={ // the current bit image
 B00000000,    // B0 == B00000000?
 ...
}
...

void loop() {
  matrix =  i_face;   // error assigning the predefined bitmap to the working array
}
}

In fuction ´void loop()´:
error: invalid array assignment

I looked at array - Arduino Reference and found examples for declaring and accessing arrays - but not for assigning / copying arrays.

So as far as I have understood arrays hold an address for a reserved memory space - and If I want to assign the value of one array to another I cannot use A=B - as they simply hold a memory reference. To copy the contents of B to A I need to iterate over each element and copy that (making it somewhat clumsy and costly).

  • Did I miss something about "whole" array operation?
  • If it is true, would it be possible to add some information to the Array Reference page?

Did I miss something about "whole" array operation?

Yes there are not any in this language.

Grumpy_Mike:

Did I miss something about "whole" array operation?

Yes there are not any in this language.

I was hoping for something like strcopy for "normal" arrays. Or pointers or idk.

was hoping for something like strcopy for "normal" arrays. Or pointers or idk.

Hope is such a cruel mistress.

Interestingly, if you wrap your arrays in a struct, you can assign structs directly.

This is what you can do in C/C++ to achieve array assignment.

#include <string.h>
...
// matrix = i_face
memcpy(matrix, i_face, sizeof(matrix));
// program memory (constant values)
const byte c_face[8] PROGMEM = { ..... };
memcpy_P(matrix, c_face, sizeof(matrix));
// matrix = 0;
memset(matrix, 0, sizeof(matrix));
// matrix == i_face
memcmp(matrix, i_face, sizeof(matrix)) == 0

The include is not really needed in Arduino as this is done in Arduino.h. I like the answer about wrapping the array in a struct.

struct array_t {
  byte element[8];
};
array_t matrix, i_face;
matrix = i_face;

There are more tricks to be played in C++ as operators may be defined for the struct/class. With a template class you can also handle different array sizes and avoid using the heap (malloc/free, new/delete).
Cheers!

I was hoping for something like strcopy for "normal" arrays. Or pointers or idk.

memcpy() works, if the destination array is larger than, or the same size as, the source array.

Pointers can be made to point to different arrays, too.

Thank you PaulS and kowalski especially for the examples - somehow my last reply got lost.

Would it be possible to add a section to the Arduino Reference page for Arrays - as it does not go into working with arrays as a whole, but only on the containing datatypes.

Would it be possible to add a section to the Arduino Reference page for Arrays

A) Almost no chance of affecting change to the Arduino reference, calls for all sorts of documentation changes seem to fall on deaf ears.
B) Arrays must be well covered by 10,000 other online references and tutorials.
C) That said this is a very common problem encountered by beginner programmers and the Arduino reference does already cover some C/C++ constructs, most notably the operators and control structures. So there may be an argument for adding arrays as they are fundamental to decent programming. See point A.


Rob

kowalski:
There are more tricks to be played in C++ as operators may be defined for the struct/class. With a template class you can also handle different array sizes and avoid using the heap (malloc/free, new/delete).
Cheers!

GCC also supports compound literals. Not something which is standard.

Assign new array to old array using kowalski's struct & compund literal:

//Initialisation, this is standard use.
array_t matrix = {{ 'a','b','c','d','e','f','g','\0' }};

//Assignment using compound literal
matrix = ( array_t  ){{ 'h','i','j','k','l','m','n','\0' }};

Using a template version of memcpy ( passing size in like standard memcpy, 3 params ):

template< typename T >
  T *arrcpy( T *dest, const T *source, int size ){
    while( --size >= 0x00 ){ dest[ size ] = source[ size ]; }
    return dest;
  }

Using a template version of memcpy specifically for arrays ( no third parameter to pass size ):

template< typename T, size_t N >
  T *arrcpy( T (&dest)[N], const T (&source)[N] ){
    int size = N;
    while( --size >= 0 ){ dest[ size ] = source[ size ]; }
    return dest;
  }