In Arduino, do multiples of the same value type take up more bits than an array with same number of that value type?
In other words:
//Does this
byte a = x;
byte b = y;
byte c = z;
//Take up the same number of bits as this?
byte letter[3] = {x, y , z};
Or does the answer vary based on the value type?
So:
//Maybe this
byte a = x;
byte b = y;
byte c = z;
//Takes up fewer bits than this
byte letter[3] = {x, y, z};
//But this
long a = x;
long b = y;
long c = z;
//Takes up more bits than this?
long letter[3] = {x, y, z};
Any single data type takes the space it takes and multiples take a multiple of that, no matter how they are declared (single or array). So three individual longs take up the same space as an array of long of size 3.
Arrays are a matter of convenience. if I have 256 values, then declaring 256 and referencing variables is a pain, plus you can't use loops to manipulate the data. Arrays are much better in that situation.
byte flag = 0; //No bits set
flag |= _BV(1); //Set bit 1.
if (flag & _BV(1)){
//If bit one is true
flag &= ~_BV(1); //Maybe clear it again
flag |= (_BV(2) | _BV(3)); //Set bits 2 and 3.
}
if (flag & (_BV(2) | _BV(3))){
//If bits 2 and 3 are set
flag &= ~_BV(2); //Maybe clear bit 2
}
if (!(flag & _BV(2)) && (flag | _BV(3))){
//If bit 3 is set, and bit 2 isn't
}
I had some hope that there might be a technique similar to packing several true/false values into a single byte
There are for quantities that are less than one byte or word (like the bit flags you are referring to). For example, if you know that a certain value will never exceed 15 (4 bits) then you can pack 2 of those in the hi and low nybble of a byte. Or if a value is 0-7 (3 bits) then 5 can fit in a 16 bit word, etc. This is not automatic, though, and you will need to manage the storage, saving and retrieving through your own code.
It comes down to a tradeoff between execution speed and RAM - if there is enough data that the added complexity would save lots of memory, then it makes sense. Otherwise, for me, ease of understanding (now and in future, when I come back to look at the code) is a higher priority than saving a few bytes.
BitFields are useful for interpreting irregular data but when used for declaring types they suffer. The elements of a bit field are non-addressable unlike standard struct members. Also due to their definition being implementation defined they are not portable.
I wrote a class not to long ago to create a bit sized boolean style array, I have not completed the hardware that I intended it for so it still remains untested. It allows reading and writing of elements just like an array, also it uses the smallest possible data types for the number of elements ( uint8_t for 256 elements or less, uint32_t for 4294967295 elements ).