[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