[Utu-emt-prog2-info] clase 2 Parámetros por valor y por referencia
Federico Kouyoumdjian
fedekp en autistici.org
Vie Jul 15 18:39:08 CEST 2011
fuente:
http://www.etnassoft.com/biblioteca/introduccion-al-desarrollo-de-software/
2.12.3. Parámetros por valor y por referencia
El paso de parámetros se refiere a la acción de transformar los
parámetros formales a parámetros reales; es decir, de asignar un
contenido a las variables que representan a los argumentos:
tipo funcion_llamada( parámetro_formal_1, parámetro_formal_2, ... );
funcion_llamadora( ... )
{
/* ... */
funcion_llamada( parámetro_real_1, parámetro_real_2, ... )
/* ... */
} /* funcion_llamadora */
En este sentido, hay dos posibilidades: que los argumentos reciban el
resultado de la evaluación de la expresión correspondiente o que se
sustituyan por la variable que se indicó en el parámetro real de la
misma posición. El primer caso, se trata de un paso de parámetros por
valor, mientras que el segundo, se trata de un paso de variable
(cualquier cambio en el argumento es un cambio en la variable que consta
como parámetro real).
El paso por valor consiste en asignar a la variable del parámetro formal
correspondiente el valor resultante del parámetro real en su misma
posición. El paso de variable consiste en sustituir la variable del
parámetro real por la del parámetro formal correspondiente y,
consecuentemente, poder emplearla dentro de la misma función con el
nombre del parámetro formal.
En C, el paso de parámetros sólo se efectúa por valor; es decir, se
evalúan todos los parámetros en la llamada y se asigna el resultado al
parámetro formal correspondiente en la función.
Para modificar alguna variable que se desee pasar como argumento en la
llamada de una función, es necesario pasar la dirección de memoria en la
que se encuentra. Para esto se debe de emplear el operador de obtención
de dirección (&) que da como resultado la dirección de memoria en la que
se encuentra su argumento (variable, campo de tupla o elemento de
matriz, entre otros). Este es el mecanismo que se emplea para que la
función scanf deposite en las variables que se le pasan como argumento
los valores que lee.
Por otra parte, en las funciones llamadas, los parámetros formales que
reciben una referencia de una variable en lugar de un valor se deben
declarar de manera especial, anteponiendo a su nombre un
asterisco. El asterisco, en este contexto, se puede leer como el
“contenido cuya posición inicial se encuentra en la variable
correspondiente”. Por tanto, en una función como la mostrada a
continuación, se leería “el contenido cuya posición inicial se encuentra
en el parámetro formal numerador” es de tipo entero. De igual forma se
leería para el denominador:
void simplifica( int *numerador, int *denominador )
{
int mcd;
mcd = maximo_comun_divisor( *numerador, *denominador );
*numerador = *numerador / mcd;
*denominador = *denominador / mcd;
} /* simplifica */
/* ... */
simplifica( &a, &b );
/* ... */
Aunque se insistirá en ello más adelante, hay que tener presente que el
asterisco, en la parte del código, debería leerse como “el contenido de
la variable que está almacenada en la posición de memoria del argumento
correspondiente”. Por lo tanto, deberemos emplear *parámetro_formal cada
vez que se desee utilizar la variable pasada por referencia.
2.12.4. Ejemplo
El programa siguiente calcula numéricamente la integral de una función
en un intervalo dado según la regla de Simpson. Básicamente, el método
consiste en dividir el intervalo de integración en un número determinado
de segmentos de la misma longitud que constituyen la base de unos
rectángulos cuya altura viene determinada por el valor de la función a
integrar en el punto inicial del segmento. La suma de las áreas de estos
rectángulos dará la superficie aproximada definida por la función, el
eje de las X y las rectas perpendiculares a él que pasan por los puntos
inicial y final del segmento de integración:
/* Fichero: simpson.c */
#include <stdio.h>
#include <math.h>
double f( double x )
{
return 1.0/(1.0 + x*x);
} /* f */
double integral_f( double a, double b, int n )
{
double result;
double x, dx;
int i;
result = 0.0;
if( (a < b) && (n > 0) ) {
x = a;
dx = (b-a)/n;
for( i = 0; i < n; i = i + 1 ) {
result = result + f(x);
x = x + dx;
} /* for */
} /* if */
return result;
} /* integral_f */
void main( void )
{
double a, b;
int n;
printf( "Integración numérica de f(x).\n" );
printf( "Punto inicial del intervalo, a = ? " );
scanf( "%lf", &a );
printf( "Punto final del intervalo, b = ? " );
scanf( "%lf", &b );
printf( "Número de divisiones, n = ? " );
scanf( "%d", &n );
printf( "Resultado, integral(f)[%g,%g] = %g\n", a, b, integral_f( a, b,
n ) ); /* printf */
} /* main */
Más información sobre la lista de distribución Utu-emt-prog2-info