2011-01-23 13 views
35

A continuación se muestra un fragmento del libro C Programación Solo las preguntas más frecuentes. ¿No está mal, ya que las matrices nunca se pueden pasar por referencia?Pase una matriz a una función por valor

VIII.6: ¿Cómo se puede pasar una matriz a una función por valor?

Respuesta: Una matriz se puede pasar a una función por valor declarando en la función llamada el nombre de la matriz con corchetes ([ y ]) unidos al extremo. Cuando llame a la función , simplemente pase la dirección de la matriz (es decir, el nombre de la matriz) a la función llamada. Por ejemplo, el siguiente programa pasa a la matriz x[] a la función llamada byval_func() por valor:

El parámetro int[] le dice al compilador que la función byval_func() tendrá un argumento- una matriz de enteros. Cuando la función byval_func() se llama, que pasa la dirección de la matriz a byval_func():

byval_func(x); 

Debido a que la matriz se pasa por valor, una copia exacta de la matriz es hizo y se coloca en el apilar. La función llamada recibe esta copia de la matriz y puede imprimirla. Debido a que la matriz pasada a byval_func() es una copia de la matriz original, modificando la matriz dentro de la función byval_func() tiene ningún efecto sobre la matriz original.

+0

Esto es cierto para las estructuras: puede pasarlas por valor (sobre la pila) o por referencia, pero no para las matrices. – sinelaw

+13

Esto está en un libro sobre C, ¿verdad? Veo que data de 1995, pero esto ya estaba completamente mal entonces. –

+24

Si eso es lo que dice en el libro, tiene que descartar el libro, contiene información errónea sobre un problema básico y quién sabe qué otra información errónea sobre qué otros asuntos. El último párrafo citado es absurdo: si modifica la matriz en la función llamada, también está modificando la matriz en la función de llamada, porque las matrices no se pasan por valor en C. –

Respuesta

53

Debido a que la matriz se pasa por valor, una copia exacta de la matriz se hace y se colocan en la pila.

Esto es incorrecto: la matriz en sí misma no está siendo copiado, solamente una copia del puntero a su dirección se pasa al destinatario de la llamada (que se encuentra en la pila). (Independientemente de si declara el parámetro como int[] o int*, es decays into a pointer.) Esto le permite modificar el contenido de la matriz desde la función llamada. Por lo tanto, este

Debido a que la matriz pasada a byval_func() es una copia de la matriz original, modificar la matriz dentro de la función byval_func() no tiene efecto en la matriz original.

es completamente erróneo (felicitaciones a @Jonathan Leffler por su comentario a continuación). Sin embargo, reasignar el puntero dentro de la función no cambiará el puntero a la matriz original fuera de la función.

+0

Creo que tiene razón . – sinelaw

+0

Él sí lo es. En C++, por supuesto, puede tener objetos de matriz pasados ​​por valor, pero en C, una matriz es solo un puntero. –

+4

StefanHållén: No puede pasar (o devolver) matrices por valor en C o C++, puede pasar matrices por referencia en C++ porque C++ tiene tipos de referencia. –

45

Grabar ese libro.Si quiere una C FAQ real que no fue escrita por un programador principiante, use esta: http://c-faq.com/aryptr/index.html.

Sintaxis-sabia, en sentido estricto se habla no puede pasar una matriz por el valor en C.

void func (int* x); /* this is a pointer */ 

void func (int x[]); /* this is a pointer */ 

void func (int x[10]); /* this is a pointer */ 

Sin embargo, para el registro, hay un truco sucio en C que no permiten pasar de una ordenar por valor en C. ¡No intente esto en casa! Porque a pesar de este truco, todavía no hay razón para pasar una matriz por valor.

typedef struct 
{ 
    int my_array[10]; 
} Array_by_val; 

void func (Array_by_val x); 
+5

Cosméticos para el tercer ejemplo significa que puede hacer un 'sizeof (array)/sizeof (array [0])' en la función – Ulterior

+1

@Ulterior ¿No sería agradable si funciona? Pero, por desgracia, estás equivocado, el estándar C no es tan inteligente. Intenta esto: 'void func (int arr [10]) {printf (" No, todavía soy un puntero, mi tamaño es% d. ", Sizeof (arr)); } ' Imprimirá 4 u 8 en una PC, no 40 como es de esperar. – Lundin

+1

"Porque a pesar de este truco, todavía no hay razón para pasar una matriz por valor". -- ¿por qué? – Antinous

1

en C y C++ NO es posible pasar un bloque completo de la memoria por el valor como un parámetro para una función, pero se les permite pasar su dirección. En la práctica, esto tiene casi el mismo efecto y es una operación mucho más rápida y más eficiente.

Para estar seguro, puede pasar el tamaño de matriz o poner el calificador const antes del puntero para asegurarse de que el destinatario no lo cambie.

+17

Las estructuras y uniones se pueden pasar por valor. –

-11
#include<stdio.h> 
void fun(int a[],int n); 
int main() 
{ 
    int a[5]={1,2,3,4,5}; 
    fun(a,5); 
} 
void fun(int a[],int n) 
{ 
    int i; 
    for(i=0;i<=n-1;i++) 
     printf("value=%d\n",a[i]); 
} 

Por este método podemos pasar la matriz por valor, pero en realidad la matriz está accediendo a través de la dirección de su base que en realidad la copia en la pila.

+2

No, eso no * pasa la matriz por valor. El parámetro es un puntero. –

+0

Y si 'fun' cambia el valor de' a [0] ', ese cambio sería visible en' main'. –

+0

así que cómo pasamos la matriz por valor. En esto, hay una matriz de pasos simple y la matriz también se comporta como un puntero constante, por lo que cuando pase una matriz por valor, simplemente significa que la está pasando por un puntero. Si tiene algún ejemplo, por favor dígame. –

Cuestiones relacionadas