2009-12-17 12 views
14

Estoy tratando de utilizar pasar por referencia en C para que la función pueda modificar los valores de los parámetros que se le pasen. Esta es la función de firma:Pase por referencia en C

int locate(char *name, int &s, int &i) 

Sin embargo, cuando intento compilar que me sale este error que se refiere específicamente a la línea anterior:

error: expected ‘;’, ‘,’ or ‘)’ before '&' token

Si quito el '&' el programa compilará , pero no funcionará correctamente, obviamente. ¿Qué pasa aquí? ¿Cómo puedo hacer una llamada por referencia?

+7

¿Por qué crees que pasar por referencia debería funcionar en C?C no tiene pase por referencia. –

+2

Claro que sí. Simplemente llama a sus referencias "punteros". – Crashworks

+7

"punteros" no son "pasar por referencia". Pase lo que pase a una función en C, se pasa por valor. Puede suceder que lo que se pasa sea un puntero, en cuyo caso, la función recibe una * copia del puntero *, y puede usar esa copia para cambiar el valor apuntado por el puntero, pero el puntero se pasa por valor . –

Respuesta

34

C no tiene referencias. Tiene que pasar un puntero a la variable que desea modificar:

int locate(char *name, int *s, int *i) 
{ 
    /* ... */ 

    *s = 123; 
    *i = 456; 
} 

int s = 0; 
int i = 0; 
locate("GMan", &s, &i); 

/* s & i have been modified */ 
7

C no admite pase por referencia. Tendrá que C++ para hacerlo de la manera que está escrito, o modificar en

int locate(char *name, int *s, int *i) 

y pasar punteros a la segunda y tercera variables de parámetros.

20

C no tiene variables de referencia, pero se puede considerar como referencia puntero constante a los datos así,

Hacer puntero const a los datos como este de manera que el punto puntero no puede con otros datos, pero los datos que se apunta por el que puede ser cambiado

int locate (char *name, int * const s, int * const i) 
+0

+1 para sugerencia const puntero – Qberticus

1

No puede hacer esto en c. c no tiene referencia, puede usar puntero en su lugar.

1

Si desea utilizar el método de paso por referencia para modificar un parámetro utilizado en la llamada a la función, siempre use los punteros como argumentos formales de la función.

De ahí que en lugar de utilizar este uso

int locate(char *name, int &s, int &i) 

,

int locate(char *name, int *s, int *i) 

Cuando va a llamar a esta función, es posible utilizar

.........

int a=5; 
int d=10; 
char c='A'; 
int result; 

result=locate(&c, &a, &d); 

Espero que todo sea claro ar ahora,

Para obtener más idea de pasar por valor o el paso por referencia y cuál es mejor, esta fuente es bueno para los principiantes

http://www.learnc.net/call-by-reference.php

divertirse.

+0

Estoy bastante seguro de que 'nombre' no se supone que es un puntero a un solo' char'. – Downvoter

1

Parece que las respuestas anteriores no tienen contexto y no abordan la propiedad de que los punteros C están sobrecargados. Es completamente justo afirmar que C "pasa por referencia". Un puntero es una referencia, también. Sin embargo, más formalmente, una "referencia" C es el mecanismo para representar la dirección de memoria de un símbolo.

  • Un puntero es simplemente una variable en la memoria cuyo valor se trata como una dirección .
  • Una referencia es simplemente el valor literal de una dirección de memoria.
  • El lenguaje C permite pasar por referencia, ¡pero solo en el contexto correcto!

La separación del contexto es la definición de la firma y la invocación de la firma.

Considere las primitivas int a = 0x22e8; y en otro lugar declaramos int* b = &a; (accederé a las funciones en un minuto).

Podríamos visualizar esto en memoria (se supone endianness no importa para este ejemplo):

... 
0x00000200:  22e8  ; this is the variable for int a's literal value: 
           ; a == 0x000022e8 
           ; &a == 0x00000200 
0x00000???:  9090  ; ... more code ... 
0x00000400:  0200  ; this is pointer b pointing to a's address: 
           ; b == 0x00000200 
           ; *b == 0x000022e8 
           ; &b == 0x00000400 
... 

Es fácil ver que podemos asignar un puntero a cualquier dirección sin ningún truco especial. Un puntero es solo una variable, pero C nos permite hacer referencia a la dirección a la que apunta; podemos "quitar la referencia" del puntero de su dirección de valor para tratar en cambio el puntero como el valor subyacente de su ponente durante un contexto de invocación: while (*b == a) .... Podríamos invocar fácilmente b == &a.

Al aplicar esto a las llamadas a funciones, debe separar el contexto de la definición de función (firma) frente a la invocación para diferenciar el pase por referencia.

int* foo(int* blah, int nah) { .. }  // signature definition context: 
             // These are parameters 
... vs ... 

b = foo(&a, 4);      // invocation context: 
             // These are arguments 

En la definición de una firma de función, que no están diciendo al compilador que se refieren a un argumento se accede desde — el tiempo de ejecución ni siquiera sabe todavía! No tiene sentido definir void bar(int &blah) {...}. En su lugar, utilizamos la sintaxis del puntero desreferenciado — "cualquier argumento que se pase se cargará en la dirección apuntada a" — para hacer referencia al valor del argumento deseado cuando se produce el tiempo de ejecución. Por lo tanto, C puede pasar argumentos por referencia.

Los contextos de las definiciones de firmas de funciones y de las llamadas a funciones cambian la forma en que el compilador examina la sobrecarga del puntero frente a la referencia, y cómo el tiempo de ejecución realmente puede abordarlos.

+0

Para ser más claros, una sintaxis real de "referencia" en C es la sintaxis ampersand: '& a'.Y también" pasar por referencia ", el' b = foo (& a, 4) ', ocurre en tiempo de ejecución durante la ejecución de la llamada a función; y definición de firma, el 'int * foo (int * a, int nah) {..}' es la configuración para permitir el paso de la referencia. – ToFue

0

(He estado usando C por un tiempo pero soy bastante nuevo en algunos conceptos en C. Estoy tratando de responder a esto según mi leal saber y entender, siéntete libre de corregirme si estoy equivocado)

Cuando dices pasar por referencia, pasas la dirección y lo haces para que uses punteros que apuntan a las direcciones. Entonces, debe pasar los punteros al prototipo de su función, pero lo que está haciendo es pasar la dirección directamente.

Lo que intenta su función es quitar la referencia (usando &) su puntero, pero nunca tuvo un puntero a los parámetros 's' y 'i' para desviarlo.

La forma correcta de hacerlo para el prototipo de la función/definición es

int locate(char *name, int *s, int *i) 

y cuando se tiene que llamar a esta función que utilice la siguiente declaración en la función principal o llamando

int locate(char *name, &s, &i) 
Cuestiones relacionadas