2010-02-20 20 views
7

Supongamos que tengo una serieDevuelve una matriz en C++

int arr[] = {...}; 
arr = function(arr); 

tengo la función como

int& function(int arr[]) 
{ 
//rest of the code 
     return arr; 
} 

¿Qué error ¿Estoy haciendo aquí ??

+2

¿Por qué usted (o simplemente cualquier desarrollador) está escribiendo este código loco? : \ – kennytm

+0

@ manugupt1: ¿Es su intención pasar la matriz a la función como una copia? –

Respuesta

7
int& function(int arr[]) 

En esta función arr es un puntero, y no hay manera de convertir de nuevo a un conjunto nuevo. Es lo mismo que

int& function(int* arr) 

int arr[] = {...}; 
arr = function(arr); 

Suponiendo que la función arregló para devolver una referencia a la matriz, esto todavía no funcionaría. No puedes asignar a una matriz. A lo sumo se podría enlazar el resultado de una "referencia de una serie de X enteros" (usando un typedef porque la sintaxis obtendría muy feo lo contrario):

typedef int ten_ints[10]; 

ten_ints& foo(ten_ints& arr) 
{ 
    //.. 
    return arr; 
} 

int main() 
{ 
    int arr[10]; 
    ten_ints& arr_ref = foo(arr); 
} 

Sin embargo, no está nada claro cuál es el código en su pregunta se supone que lograr. Cualquier cambio que realice en la matriz en la función será visible para la persona que llama, por lo que no hay razón para tratar de devolver la matriz o asignarla de nuevo a la matriz original.


Si desea una matriz de tamaño fijo que se puede asignar a y pasar por valor (con el contenido que se copia), hay std::tr1::array (o boost::array). std::vector también es una opción, pero es una matriz dinámica, por lo que no es un equivalente exacto.

1
  • Una matriz como argumento es en realidad un puntero. Las matrices se "insertan" automáticamente a los punteros si se proporcionan como argumento
  • No se puede asignar una matriz a otra matriz en C/C++. Deberá usar un memcpy o loop para copiar los valores.
  • Si la función cambia el argumento arr, en realidad cambia el valor de la variable arr dada por la persona que llama. De nuevo porque la matriz es en realidad un puntero. Entonces, en la persona que llama, arr se asigna a arr, lo cual es inútil aquí.
4

La semántica del paso y el retorno del conjunto puede ser bastante confusa. Use un std :: vector en su lugar.

+0

o boost :: array, si está disponible. – Macke

+9

Si bien este es ciertamente un buen consejo, ** ni siquiera responde remotamente la pregunta ** .. –

+0

@Andreas "¿Qué error estoy cometiendo aquí?" - el error de no usar un vector. –

3

Está devolviendo una referencia a una int, no una referencia a una matriz.

que desee:

(int*)& function(int arr[]) 
{ 
    /// rest of the code 
    return arr; 
} 

Dicho esto, como otros ya se ha dicho, eso no es una buena práctica.

+3

En realidad, eso devuelve una referencia a un puntero y 'arr' tampoco es una matriz. –

+1

Además de lo que dice @gf, también es un error de sintaxis. –

0

Bueno, arr es compatible con int*, no int&. Tu código no se compilará Tal vez usted quería return arr[0]?

6

Como han dicho otros, hay mejores opciones como los contenedores STL y la pregunta más interesante es por qué necesita devolver la matriz a una función que ya la tiene dentro del alcance.

Dicho esto, no se puede pasar o matrices de volver por el valor y la necesidad de evitar la descomposición de la matriz a un puntero (véase, por ejemplo here), ya sea mediante el uso de punteros o referencias a ella:

int (&f(int (&arr)[3]))[3] 
{ 
    return arr; 
} 

Si no desea codificar el tamaño, puede utilizar las funciones de plantilla:

template<size_t n> 
int (&f(int (&arr)[n]))[n] 
{ 
    return arr; 
} 
+0

Esa es una sintaxis seria _twisted_. Merecen muchos elogios incluso por obtenerlo aquí mismo. Me siento libre de usar typedefs ahora que sé _cómo es posible que haya escrito eso para el compilador sin _... +1 – sehe

+0

Suponiendo que me gustaría codificar un getter para una matriz de tamaño fijo y quiero el método así como la matriz a la que se hace referencia ser const - ¿cómo lo haría sintácticamente? De esta manera: int const (& GetArray() const) [3] {return mArray; }? – Bjoern

+0

@Bjoern: 'typedef int A [3]; const A m; const A & f() const {return m; } '? –

0

uso std :: vector como este.

std::vector<int> function(const std::vector<int>& arr) 
{ 
    return arr; 
} 

Una matriz como

int arr[] = {...}; 

no es útil para ser devueltos desde una función porque no es capaz de copiarse a sí mismo.

0

Si no es necesario, no lo use.que sólo puede pasar una referencia de una matriz, como por ejemplo:

void foo(std::vector<int> &v) { 
    for (int i = 0; i < 10; ++ i) { 
     v.push_back(i); 
    } 
} 

si utiliza:

std::vector<int> foo() { 
    std::vector<int> v; 
    for (int i = 0; i < 10; ++ i) 
     v.push_back(i); 

    return v; 
} 

habrá un proceso de copia del contenedor, el costo es caro.

FYI: NRVO tal vez eliminar el costo

1

Creo que su mejor opción es devolverlo como un puntero a una matriz. Aquí está un ejemplo: obras

{ 
    ... 
    int newLength = 0; 
    int* arr2 = ChangeArray(arr, length, newLength); 
    ... 
    delete[] arr2; 
} 

int* ChangeArray(int arr[], int length, int& newLength) 
{ 
    // reversing the number - just an example 
    int* newArr = new int[length]; 
    for(int i = 0; i < length; i++) 
    { 
     newArr[i] = arr[length-i-1]; 
     newLength++; 
    } 
    return newArr; 
} 
3

raíz y no parece desordenado o mal comprensible!

int* returnarray(int a[]) 
{ 
    for (unsigned int i = 0; i < 3; i++) 
    { 
     a[i] *= 2; 
    } 
    return a; 
} 

int main(int argc, char* argv[]) 
{ 
    int arr[3] = {1,2,3}; 
    int* p = returnarray(arr); 
    for (unsigned int i = 0; i < 3; i++) 
    { 
     cout << "p[" << i << "] = " << p[i] << endl; 
    } 
     cin.get(); 
     return 0; 
} 
Cuestiones relacionadas