Look at the "for" statement. start at the highest index and work backwards. Be careful at the ends.
Interestingly, your original code with memcpy doesn't look too bad, assuming memcpy works nicely with overlapping memory spaces in all implementations of c/c++. Is this a school exercise ?
In this case, I don't think for loop will work maybe you will notice that if you use a for loop to do left shit for an array you will see the latter data will be covered by the previous one if you try.
6v6gt:
Exactly. You can surely see a pattern there?
recv[ x ] = recv[ x -1] ;
Look at the "for" statement. start at the highest index and work backwards. Be careful at the ends.
Interestingly, your original code with memcpy doesn't look too bad, assuming memcpy works nicely with overlapping memory spaces in all implementations of c/c++. Is this a school exercise ?
Yes, similarly. For a left shift of the array I can do this:
for(int i=3;i>0;i--){
recv*=recv[i-1];* } but for a right shift of the array I can't do this: for(int i=0;i<3;i++){ recv*=recv[i+1];* } somehow i printed out the array the latter data get covered by the previous one.
Are you interchanging left and right when you talk about a direction shift ?
You can, incidentally, use memmove (but NOT memcpy) for overlapping memory spaces.
PaulS:
The google search term is "circular array".
Here is crude implementation using the OP's example:
int recv[4] = {4, 30, 60, 2} ;
int arrLen = sizeof( recv) / sizeof( recv[0] ) ;
int shift = -1 ; // positive is shift left ; negative is shift right e.g. -1 = shift right 1 ; +2 = shift left 2 ;
// print array with shift
for ( byte i = 0 ; i < arrLen ; i++ ) {
Serial.println( recv[ ( arrLen + shift + i ) % arrLen ] ) ; // % can be expensive ; force positive return
}
Make the array size 2N and you can get rid of the modulo operator and just use an 'and' mask to keep the lower N bits of the index. Use unsigned (uint8_t, uint16_t) for all indexing operations so the value properly wraps around when you subtract from zero and apply the mask.
But, the issue seems moot. It's stupid to shift the whole array around if you can accomplish the same thing by changing a variable that indexes into the array.
It's stupid to shift the whole array around if you can accomplish the same thing by changing a variable that indexes into the array.
I would rephrase that as it's not necessary to shift the whole array around if you can accomplish the same thing by changing a variable that indexes into the array. But bear in mind that this is at the expense of extra processing in the program.
gfvalvo:
But, the issue seems moot. It's stupid to shift the whole array around if you can accomplish the same thing by changing a variable that indexes into the array.
Indeed but you also suggested this
gfvalvo:
Make the array size 2N and you can get rid of the modulo operator . . .
Rounding up an array to the next power of 2 could be very extravagant, especially if your array was say 1025 bytes. A small MCU may not tolerate it.
UKHeliBob:
But bear in mind that this is at the expense of extra processing in the program.
I wouldn’t call it an “expense” as the “extra processing” would likely require fewer processor cycles than shuffling around the whole array.
6v6gt:
Rounding up an array to the next power of 2 could be very extravagant, especially if your array was say 1025 bytes. A small MCU may not tolerate it.
I'm going to go out on a limb and say that manipulating an index is still more efficient even if your array is arbitrary size and you must use the modulo operator (or an ‘if’ statement).
The 2^N technique is simply an additional optimization that may or may not be applicable.