Swap arrays by using pointers in C++

2019-02-12 14:41发布

问题:

I have two arrays of pointers to doubles that I need to swap. Rather than just copy the data within the arrays, it would be more efficient just to swap the pointers to the arrays. I was always under the impression that array names were essentially just pointers, but the following code receives a compiler error:

double left[] = {1,2,3};
double right[] = {9,8,7};

double * swap = left;
left = right; // Error "ISO C++ forbids assignment of arrays"
right = swap; // Error "incompatible types in assignment of `double*' to `double[((unsigned int)((int)numParameters))]'"

Creating the arrays dynamically would solve the problem, but can't be done in my application. How do I make this work?

回答1:

Arrays are not the same as pointers and cannot be swapped in the way you describe. To do the pointer swap trick, you must use pointers, either dynamically allocate the memory, or use pointers to access the data (in the way Daniel has described).



回答2:

double array_one[] = {1,2,3};
double array_two[] = {9,8,7};

double *left = array_one;
double *right = array_two;

double * swap = left;
left = right;
right = swap;

Works nicely.

edit: The definitions array_one and array_two shouldn't be used and the doubleleft and doubleright should be as public as your original left and right definitions.



回答3:

C-style arrays are not pointers, but like most objects, they can be swapped with the standard std::swap():

#include <iostream>
#include <utility>
int main()
{
        double array_one[] = {1,2,3};
        double array_two[] = {9,8,7};
        std::swap(array_one, array_two);
        std::cout << "array_one[0] = " << array_one[0] << '\n';
        std::cout << "array_two[0] = " << array_two[0] << '\n';
}

Actually, looks like std::swap() for arrays is only defined in C++0x (20.3.2), so nevermind. The correct answer is, for both arrays in scope and arrays as pointers to first elements:

 std::swap_ranges(array_one, array_one + 3, array_two);


回答4:

One of the easiest ways to convince people that they're not pointers, and not easily swapped, is to show the following code:

struct ex {
  char c[4];
  double d[3];
};
struct ex a = {"foo", {1.0, 2.0, 3.0} };
struct ex b = {"bar", {6,7,8} };

Now clearly a.d and b.d are arrays. Swapping them will involve hard work, as the array {6,7,8} has to end in memory after a.c=="foo" and that means copying 3 doubles. There's no pointer in the picture.



回答5:

Try this

double *right = (double[]){9,8,7};
double *left = (double[]){8,2,3};   


回答6:

You can pass both pointers to arrays by references, and in case pointers are not const, you can just swap them:

void swap(char * & first, char * & second)
{
     std::swap(first, second);
}


回答7:

When you declare an array, the name is a pointer, which cannot be altered.

Ex:

int array[10];
int *p;

p = array; // legal
array = p; // illegal; array is a constant pointer which can't be altered.

The only way you can achieve the swap is using new pointers to the array.

This should help you:

SO question on array name as pointer