2010-08-03 10 views
8

Tengo dos matrices de punteros a dobles que necesito intercambiar. En lugar de simplemente copiar los datos dentro de las matrices, sería más eficiente simplemente intercambiar los punteros a las matrices. Siempre tuve la impresión de que los nombres de matriz eran, básicamente, enlaces, pero el siguiente código, recibe un error de compilación:Intercambie matrices utilizando punteros en C++

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))]'" 

Creación de las matrices dinámicamente resolvería el problema, pero no se puede hacer en mi solicitud. ¿Cómo hago que esto funcione?

+0

El nombre de la matriz no es un puntero. El nombre de la matriz es una dirección de su primer elemento. – doc

+1

Considerando que un puntero es una dirección a una variable.¿Por qué no puedo cambiar esas direcciones? – thornate

+2

@thornate: la diferencia más relevante entre un nombre de matriz y una variable de puntero es que un nombre de matriz no es un valor l, por lo tanto, no puede ser el objetivo de una instrucción de asignación. Por lo tanto, la forma de hacer lo que desea es asignar los nombres de la matriz a las variables del puntero, que _are_ lvalues, luego cambiarlos. No hay forma de señalar el punto "izquierdo" o "derecho" a otra cosa, una vez que han sido definidos. –

Respuesta

1

probar este

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

No puedo cambiar la forma en que se crearon las matrices; se pasan a la función que estoy creando y no puedo editar la forma en que se definieron. – thornate

+1

Esta sintaxis es una característica C99 que no está en C++ –

7
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; 

funciona muy bien.

edición: Las definiciones array_one y array_two no se deben utilizar y la doble doble a la izquierda y la derecha deben ser tan pública como su izquierda original y las definiciones correctas.

+0

Parece que funciona bien. – WarmWaffles

+0

Solo funciona bien si quiero usar la izquierda y la derecha después de ese punto; De hecho, necesito cambiar array_one y array_two, para que también se intercambien en la función que llamó a este. – thornate

+0

@thornate no hay función en su ejemplo de pregunta. Tal vez podría resolverse pasando punteros a una función? Pero sería mejor si pudieras editar tu publicación y explicar qué es exactamente lo que estás tratando de lograr. – doc

4

matrices de tipo C no son punteros, pero al igual que la mayoría de los objetos, que se pueden intercambiar con la norma 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'; 
} 

En realidad, parece que std :: swap() para las matrices se define sólo en C++ 0x (20.3.2), así que nunca importa. La respuesta correcta es, para ambas matrices en el alcance y matrices como punteros a primeros elementos:

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

La mejor y más simple respuesta aquí. –

-2

Cuando se declara una matriz, el nombre es un puntero, que no puede ser alterado.

Ex:

int array[10]; 
int *p; 

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

La única manera de lograr el canje está utilizando nuevos indicadores de la matriz.

Esto debería ayudar a:

SO question on array name as pointer

+0

'sizeof (array)' probará que 'array' no es un puntero. Pero se convierte en un puntero cuando lo necesita. – MSalters

12

Las matrices no son los mismos que los punteros y no pueden ser cambiados en la forma en que usted describe. Para hacer el truco de intercambio de puntero, debe usar punteros, asignar dinámicamente la memoria o usar punteros para acceder a los datos (de la manera que Daniel ha descrito).

+11

Las matrices no son punteros. Las matrices no son punteros. Las matrices no son punteros. +1 – xtofl

+1

Hablando de asignar dinámicamente la memoria, puede usar std :: vector, que tiene un método 'swap()' para intercambiar los punteros subyacentes. – JWWalker

-1

Puede pasar ambos punteros a las matrices de referencias, y en caso de punteros no están const, sólo puede intercambiarlos:

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

Una de las maneras más fáciles de convencer a la gente de que ellos no son punteros, y no intercambiado con facilidad, es mostrar el siguiente código:

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} }; 

Ahora claramente a.d y b.d son matrices. Intercambiarlos supondrá un trabajo arduo, ya que la matriz {6, 7, 8} tiene que terminar en la memoria después de a.c=="foo" y eso significa copiar 3 dobles. No hay un puntero en la imagen.