deas 2015





Argumentos pasados Por Valor y Por Referencia

En las funciones vistas anteriormente, los argumentos siempre han sido pasados por el valor, esto significa que: al llamar a una función, lo que se pasa a la función son los valores de estos argumentos en el momento de la llamada, que se copian en las variables representadas por los parámetros de la función. Por ejemplo, tomar:
int x=5, y=3, z;
z = addition (x,y);
En este caso, la función addition esta pasando 5 y 3, que son copias del valor de x e y. Estos valores (5 y 3) se usan para inicializar las variables establecidas como parámetros en la definición de la función; pero cualquier modificación que se haga en estas variables dentro de la función no tendrá efecto sobre el valor de las variables y ni fuera de ella, todo esto debido a que no se pasaron a ninguna función en la llamada, tan solo eran copias de sus valores en ese momento.





Sin embargo, en ciertos casos, puede ser útil acceder a una variable externa desde dentro de una función. Para hacer eso, los argumentos se pueden pasar por referencia, en lugar de por su valor. Por ejemplo, la función duplicar en este código, duplica el valor de sus tres argumentos, haciendo que las variables utilizadas como argumentos realmente sean modificadas por la llamada. 
Para obtener acceso a sus argumentos, la función los declara como referencias. En C++, las referencias se indican con un signo de & a continuación del tipo del parámetro, como en los parámetros tomados por duplicado en el ejemplo anterior.
Cuando se pasa una variable por referencia, lo que se pasa ya no es su copia, sino exactamente la variable en sí, la variable identificada por el parámetro de la función, asociándose de algún modo con el argumento pasado a la función y a cualquier modificación en sus correspondientes variables locales dentro de la función, todo esto reflejadas en las variables pasadas como argumentos en la llamada. Veamos un ejemplo básico:





 De hecho, ab y c se convierten en alias de los argumentos pasados en la llamada a la funcion (x,y e z) y cualquier cambio en a dentro de la funcion está realmente modificando la variable "x" fuera de la función. Cualquier cambio en b modifica "y" y cualquier cambio en c modifica "z". Es por eso que cuando, en el ejemplo, la funcion duplicar modifica los valores de las variables a,b y c los valores de xy y z se ven afectados.
Si en lugar de definir duplicar como:
void duplicar (int& a, int& b, int& c)
Se definiese sin los signos ampersand como:
void duplicar (int a, int b, int c)
Entonces las variables. no se pasaran por referencia, sino porvalor, creando en su lugar copias de sus valores. En este caso, la salida del programa habria sido los valores de "x","y" y "z" sin modificarse (es decir 1,3 y 7).

Consideraciones de Eficiencia y referencias const

LLamar a una función con parámetros tomados con valor hace que se hagan copias de los valores. Esta es una operación eficiente para tipos fundamentales como int, pero si el parámetro es de un tipo compuesto grande, puede ocasionar cierta sobrecarga. Por ejemplo, considere la siguiente función:
string concatenate(string a, string b)
{
   return a+b;
} 
Esta función toma dos cadenas strings como parámetros (por valor) y devuelve el resultado de concatenarlas. Al pasar los argumentos por valor, la función obliga a b a ser copias de los argumentos pasados a la función cuando se la llama. Y si se trata de cadenas strings largas, puede esto significar copiar grandes cantidades de datos solo para la llamada a la función. Pero, esta copia se puede evitar en gran medida si ambos parámetros se pasan como referencias:
string concatenate (string& a, string& b)
{
  return a + b;
}
Los argumentos por referencia no requieren de una copia. La función opera directamente (alias de) en la string pasada como argumento, y a lo máximo puede significar la transferencia de determinados punteros para la función. En este sentido, la version de referencia de la función concatenate es más eficiente que la version que toma valores, ya que no necesita copias cadenas voluptuosas para copiar. Por otro lado, las funciones con parametros de referencia generalmente son percibidas como funciones que modifican los argumentos pasados, porque es para eso que los parámetros de referencia son realmente. La solución es para la función de garantizar que sus parámetros de referencia no vayan a ser modificados por esta función. Esto se puede hacer calificando los parámetros como constantes:
string concatenate (const string& a, const string& b)
{
     return a+b;
}
Al calificarlos como const, la función está prohibida para modificar los valores de a y de b, pero puede realmente accesar sus valores como referências (alias de los argumentos), sin tener que hacer copias de las strings.
Por lo tanto, las referencias const proporcionan funcionalidad similar a pasar argumentos por valor, pero aumentan la eficiencia para parámetros de tipos grandes. Es por eso que son extremamente populares en C++ para los argumentos de los tipos de compilación. Sin embargo, tenga en cuenta que para la mayoría de los tipos fundamentales, no existe una diferencia notable en eficiencia y en algunos casos las referencias de const pueden ser incluso menos eficientes.




Un tema bastante importante en nuestra caminata, no dejemos de practicar para conseguir nuestros objetivos. Les recomiendo que sigan mis links donde he colocado varios ejemplos básicos y complejos; sí, repítanlos para aprenderlos bien.

Publicar un comentario

Con la tecnología de Blogger.