Suppose you have two arrays and you want to swap two sub-ranges with the same number of entries. There is one requirement which may or may not be necessary:
If this is a requirement, then all one can do is perform an entry-by-entry swap, requiring then $3n$ assignments:
// Swap the 'n' entries of Array 0 going from // i0, ..., i0 + n - 1 // with the entries of Array 1 going from // i1, ..., i1 + n - 1 void ordered_array_range_swap( double array0[], std::size_t i0, double array1[], std::size_t i1, std::size_t n ) { for ( std::size_t k{ 0 }; k < n; ++k ) { // Swap the two entries double tmp{ array0[i0] }; array0[i0] = array1[i1]; array1[i1] = tmp; ++i0; ++i1; } }
You will note that we continue to use the parameters i0 and i1 throughout the algorithm:
You can see these two implementations at replit.com.
If the order can be altered, then we can reduce the number of assignments from $3n$ to $2n + 1$:
// Move the 'n' entries of Array 0 going from // i0, ..., i0 + n - 1 // to the entries of Array 1 going from // i1, ..., i1 + n - 1 // and vice versa, but the order need not // remain the same. void unordered_array_range_swap( double array0[], std::size_t i0, double array1[], std::size_t i1, std::size_t n ) { if ( n == 0 ) { return; } double tmp{ array0[i0] }; // This runs 'n - 1' times for ( std::size_t k{ 1 }; k < n; ++k ) { array0[i0] = array1[i1]; ++i0; array1[i1] = array0[i0]; ++i1; } array0[i0] = array1[i1]; array1[i1] = tmp; }
You will note that we temporarily store the first entry of the first array, and this creates a 'hole', which we fill from an entry in the second array, which creates a 'hole' there that we then fill again from the first, and so on. At the end, we fill the last two entries as appropriate. Note that declaring tmp requires one assignment, even if the assignment operator is not used.