Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Parametros Por Referencia
Parametros Por Referencia
El mecanismo que hemos estado utilizando hasta el momento para pasar parmetros del
programa principal a los procedimientos o funciones se denomina paso por valor. El
computador hace una copia del valor de los parmetros que el programa principal quiere
pasar al procedimiento o funcin, y el procedimiento o funcin trabaja con esta copia
del valor de los parmetros. Veamos un ejemplo.
#include <stdio.h>
#include <string.h>
typedef char Tpalabra [20];
typedef struct {
Tpalabra nombre;
int edad;
int nota;
} Talumno;
void escribe_datos (Talumno a)
{
printf ("Nombre: %s\n", a.nombre);
printf ("Edad: %d\n", a.edad);
printf ("Nota: %d\n", a.nota);
}
void main ()
{
Talumno alum;
strcpy (alum.nombre, "Juan");
alum.edad = 20;
alum.nota = 6;
escribe_datos (alum);
}
Vamos a aadir ahora a programa un procedimiento que sube un punto la nota del
alumno si su edad es inferior a 25. El procedimiento es el siguiente:
void sube_nota (Talumno a)
{
if (a.edad < 25)
a.nota = a.nota+1;
}
Incorpora este procedimiento al proyecto, haz una llamada desde el programa principal,
justo antes de la llamada para escribir los datos en la pantalla. Ejecuta despus el
programa y comprueba que NO funciona (debera haber subido un punto a la nota de
Juan).
Para comprender lo que pasa, ejecuta ahora paso a paso el programa y comprueba que
pasa lo siguiente:
El cdigo del programa anterior, pero usando ahora el mecanismo de paso por
referencia donde haga falta, es el siguiente:
#include <stdio.h>
#include <string.h>
typedef char Tpalabra [20];
typedef struct {
Tpalabra nombre;
int edad;
int nota;
} Talumno;
void escribe_datos (Talumno a)
{
printf ("Nombre: %s\n", a.nombre);
printf ("Edad: %d\n", a.edad);
printf ("Nota: %d\n", a.nota);
}
void sube_nota (Talumno *a)
{
if (a->edad < 25)
a->nota = a->nota+1;
}
void main ()
{
Talumno alum;
strcpy (alum.nombre, "Juan");
alum.edad = 20;
alum.nota = 6;
sube_nota (&alum);
escribe_datos (alum);
}
Haz los cambios pertinentes en el proyecto, ejecuta la nueva aplicacin y verifica que
funciona correctamente (le sube un punto a la nota de Juan).
El cambio bsico es que ahora el parmetro del procedimiento sube_nota se pasa por
referencia. Los cambios en el cdigo son:
Al acceder a los campos de la estructura, usaremos una flecha ( -> ) en vez del
punto (.).
Vuelve a ejecutar ahora el programa paso a paso y comprueba que cuando llamamos a
sube_nota, NO se hace una copia del valor del parmetro (los datos del alumno) sino
que el procedimiento trabaja directamente con los valores originales. Para comprobar
esto, verifica simplemente que la direccin de memoria donde est el campo nombre de
la variable alum es la misma que la direccin donde est el campo nombre del
parmetro a del procedimiento sube_nota. Eso indica que este procedimiento est
accediendo directamente a la informacin original. Por tanto, los cambios que haga
perdurarn incluso cuando acabe el procedimiento. Vuelve a comprobar que cuando
llamamos al procedimiento escribe_datos, esas direcciones de memoria son
diferentes, lo cual indica que se ha hecho una copia y que el procedimiento trabajar con
la copia y no con los datos originales.
Por tanto, cuando un procedimiento o funcin debe modificar la informacin que recibe
como parmetro, debe usarse el mecanismo de paso de parmetros por referencia.
3
Otro ejemplo
Aade ahora el siguiente procedimiento para asignar a la variable alum los datos ledos
del teclado.
void lee_datos (Talumno *a)
{
Tpalabra nom;
int e;
int n;
Lo nico que hemos hecho es eliminar las variables locales y colocar los datos que
leemos del teclado directamente en los campos de la estructura. Para eso, pasamos por
referencia a scanf cada uno de los campos de la estructura.
Haz estos cambios en la aplicacin y verifica que todo sigue funcionando
correctamente.
4
Ejercicio
Haz que el programa principal declare dos alumnos, lea sus datos del terminar, llame al
nuevo procedimiento nota_mayor, y escriba finalmente los datos de los alumnos en
la pantalla, usando el procedimiento escribe_datos.
5
Vectores y matrices
Esta funcin simplemente retorna la primera letra de la palabra que recibe como
parmetro (un vector de 20 caracteres). Aade la funcin al proyecto, y aade en el
programa principal una llamada pasndole como parmetro el campo nombre de un
alumno:
c = primera_letra (alum.nombre);
printf ("%c\n",c);
Ejecuta la aplicacin y verifica que funciona correctamente. Despus ejectala paso a
paso y verifica que la direccin de memoria en la que est el campo nombre del alumno
alum es la misma que la direccin en la que est el parmetro p de la funcin. Es decir,
el parmetro se ha pasado por referencia y no por valor.
Por tanto, cuando el parmetro es un vector o una matriz no hay que preocuparse de si el
paso debe ser por valor o por referencia. Siempre es por referencia.
Comprendes ahora por que en la sentencia
scanf ("%s",a->nombre);
Variables simples
Para acabar, los parmetros consistentes en valores simples (un entero, un real, o un
carcter) tambin se pueden pasar por referencia. Fjate en el ejemplo siguiente:
void dame_datos (Talumno a, int *e, int *nota, char *c)
{
*e = a.edad;
*nota = a.nota;
*c = primera_letra (a.nombre);
}
El procedimiento recibe un alumno por valor, y copia la edad y la nota en dos variables
enteras que recibe como parmetro por referencia, y copia la primera letra del nombre
en una variable de tipo carcter, que tambin recibe como parmetro por referencia.
La llamada a este procedimiento podra ser as:
dame_datos (alum,&e,&n,&c);
Fjate que en la cabecera del procedimiento, para indicar que las variables enteras y el
carcter se pasan por referencia se usa el *. Tambin debe escribirse * antes del nombre
de las variables cuando se accede a ellas dentro del procedimiento. Finalmente, hay que
escribir el signo & antes del nombre de la variable, cuando se hace la llamada al
procedimiento para pasar la variable por referencia.
Incluye estas novedades a tu aplicacin y verifica que funcionan correctamente.
7