2010-05-19 15 views
8
  • ¿Puedo pasar arreglos a las funciones de la misma manera que lo haría con primitivas como int y bool?
  • ¿Puedo pasarlos por valor?
  • ¿Cómo sabe la función del tamaño de la matriz que se pasa?
+1

Lol - answer avalanche !!!! –

Respuesta

2

Puede pasar un std::vector y un objeto similar bien diseñado por su valor (aunque esto es bastante poco común). Por lo general, pasa por referencia o referencia constante.

A C/C++ matriz, como en

void foo(int x[]) 

siempre se pasa por referencia. Además, la función no puede determinar el tamaño real del argumento pasado por la persona que llama, usted debe asumir un tamaño (o pasarlo como parámetro separado).

+2

Para ser precisos, la sintaxis de by-value para matrices descompone la matriz en un puntero al primer elemento y luego pasa ese puntero por valor. Eso difiere de pasar una matriz por referencia: void foo (int (& a) [10]) –

1
  1. Sí. Por ejemplo: void f(int a[]); y llámalo así: int myArr[size]; f(myArr);
  2. No, las matrices se pasan automáticamente por referencia. Tienes que envolver tu matriz en una estructura o clase si deseas simular pasar por valor.
  3. No es así. Tienes que pasar el tamaño tú mismo.
+0

Para ser precisos, la sintaxis de los valores por defecto para las matrices descompone la matriz en un puntero al primer elemento y luego pasa ese puntero por valor. Eso difiere de pasar una matriz por referencia: 'void foo (int (& a) [10])' –

24

¿Puedo pasar matrices a funciones tan que haría con los primitivos como int y bool?

Sí, pero solo usando punteros (es decir: por referencia).

¿Lo puedo pasar por el valor?

No. Puede crear clases que admitan eso, pero las matrices simples no.

¿Cómo sabe la función del tamaño de la matriz que se pasa?

No lo es. Esa es una razón para usar cosas como vector<T> en lugar de T *.

Aclaración

Una función puede tener una referencia o puntero a una matriz de un tamaño específico:

void func(char (*p)[13]) 
{ 
    for (int n = 0; n < 13; ++n) 
     printf("%c", (*p)[n]); 
} 

int main() 
{ 
    char a[13] = "hello, world"; 
    func(&a); 

    char b[5] = "oops"; 
    // next line won't compile 
    // func(&b); 

    return 0; 
} 

Estoy bastante seguro de que esto no es lo que el PO estaba buscando, sin embargo .

+0

Volví a subir porque estaba escribiendo exactamente la misma respuesta antes de que se volviera visible. –

+2

Las matrices en C++ se pueden pasar por referencia, en cuyo caso puede conocer el tamaño de la matriz. Por supuesto, eso no se aplica a las matrices creadas en tiempo de ejecución. – AraK

+0

@AraK - No estoy seguro de lo que quiere decir aquí. ¿Puedes agregar un ejemplo a tu respuesta? – egrunin

14

Puede pasar las matrices de la manera habitual C lo hace (las matrices decaen a los punteros), o puede pasarlas por referencia pero no pueden pasarse por valor.Para el segundo método, que llevan su tamaño con ellos:

template <std::size_t size> 
void fun(int (&arr)[size]) 
{ 
    for(std::size_t i = 0; i < size; ++i) /* do something with arr[i] */ ; 
} 

mayoría de las veces, usando std::vector u otra secuencia en la biblioteca estándar es sólo más elegante a menos que necesite matrices nativas específicamente.

+0

Eso es difícil de llevar con ellos su tamaño;) El tamaño está disponible como un argumento de plantilla (o podría tener un no- versión templada con un 'const' adecuado definido en algún lugar). No se puede obtener el tamaño de 'arr', que es donde creo que su redacción actual es un poco engañosa. – Troubadour

+0

@Troubadour: en C++, el tamaño no forma parte de la matriz, sino que forma parte del tipo de la matriz. No es necesario agregar un 'const' si lo hace sin plantilla, la única diferencia es que funcionaría en matrices de exactamente el tamaño definido en la firma:' void foo (int (& a) [3]) ' solo aceptará matrices de 3 enteros. –

+0

@dribeas: No me di cuenta el poco sobre la aplicación de la cantidad correcta de elementos. Eso está bien, gracias por informarme, pero todavía no hace que esa cantidad de elementos esté disponible dentro de la función que era mi punto. Además, no puedo obtener 'int N = 10; void fun (int (& arr) [N]) {} 'para compilar. ¿Estoy haciendo algo mal o estamos en contra de los propósitos? – Troubadour

1

Sí, puede pasarlos igual que los tipos primitivos. Sí, puede pasar por valor si realmente lo desea con algún código de contenedor, pero probablemente no debería. Tomará el tamaño del prototipo de función como la longitud, que puede o no coincidir con los datos entrantes, por lo que en realidad no lo sabe.

O!

Pase una referencia o referencia constante a un vector y sea más seguro y tenga la información de tamaño al alcance de su mano.

3

Puede pasar un arreglo, pero debe pasar el tamaño junto con él si quieres saberlo a ciencia cierta:

function(array, size); 

matrices siempre se pasan por referencia y la función se pueden escribir uno de los dos maneras:

Declaration: void function (class*, int); 
Implementation: void function(class array[]; int size) {} 

o

Declaration: void function (class*, int); 
Implementation: void function(class *array; int size) {} 

Cuando se pasa una matriz a una función de la función i n essence recibe un puntero a esa matriz, como se ve en el segundo ejemplo anterior. Ambos ejemplos lograrán lo mismo.

4

¿Puedo pasar matrices a funciones tan que haría con los primitivos como int y bool?

Sí, puedes. Pasar un nombre de matriz como argumento a una función pasa la dirección del primer elemento.

En resumen:

void foo(int a[]); 

es equivalente a

void foo(int * a); 

¿Puedo pasar por valor?

No

realmente. El "valor" que se pasa con un nombre de matriz es la dirección del primer elemento.

La única forma de pasar una copia de una matriz C-style es envolverla en class o struct que implementa la semántica de copia profunda.

¿Cómo sabe la función del tamaño de la matriz que se pasa?

No es así, a menos que tenga su función de tomar en un parámetro adicional que es el tamaño de la matriz.

+0

Re: equivalencia entre 'int a []' y 'int * b': aunque hay una diferencia: el primer formulario no le permite jugar con el puntero (por ejemplo,' a ++ 'es ilegal). –

+0

@RaphaelSP, no hay diferencia como esa. La primera forma permite 'a ++' igualmente, son completamente equivalentes. @John, "No hay forma de aceptar o pasar una copia de una matriz C-style" es erróneo cuando pedantically, sin embargo. Si ajusta la matriz en una estructura y toma el valor por estructura, la matriz envuelta se copia y la función recibe una copia de la matriz de estilo c. –

+0

@RaphaelSP: 'barra vacía (int a []) {++ a; * a = 7; } 'compila ambos en g ++ y comeau. –

2

Las matrices de estilo C se comportan de manera muy extraña cuando se pasan a funciones.Para las matrices de tamaño fijo, recomendaría std::array<int, 10> en su lugar, que se puede pasar por valor como tipos incorporados. Para las matrices de tamaño variable, recomiendo std::vector<int>, como se sugiere en otras respuestas.

Cuestiones relacionadas