deas 2015


Valores Predeterminados en los Parámetros en C++

En C++, las funciones también pueden tener parámetros opcionales, para las cuales no se requieren argumentos en la llamada, de tal manera que, por ejemplo una función con tres parámetros puede ser llamada con sólo dos. Para eso, la función debe incluir un valor predeterminado para su ultimo parámetro, que será usado por la función cuando se llama con menos argumentos. Por ejemplo:

En este ejemplo, hay dos llamadas a la función dividir. En el primero:
dividir (12)
La llamada solo pasa un argumento a la función, aunque la función tenga dos parámetros. En este caso, la función asume que el segundo parámetro es 2(observe la definición de la función, que declara su segundo parámetro como int b=2). Por lo tanto, el resultado es 6.

En la segunda llamada:
dividir (20,4)
La llamada pasa dos argumentos a la función. Por lo tanto, el valor predeterminado para (int b=2) se ignora y b toma el valor pasado como argumento, es decir 4, produciendo un resultado de 5.

En esta parte como ustedes pueden darse cuenta, estamos aprendiendo a pasar argumentos a traves de las funciones de una manera bastante detallada para que ustedes mis queridos lectores puedan entender y memorizar cada parte de este valioso tutorial. Sólo siempre voy a repetir: 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.



Funciones inline

Las funciones inline ó en línea son una función de mejora de C++ para aumentar el tiempo de ejecución de un programa. Las funciones pueden ser instruidas al compilador para que estén en línea inline, de modo que el compilador pueda reemplazar esa definición de función donde sea que se llamen. El compilador reemplaza la definición de funciones inline en línea en tiempo de compilación en lugar de referir definición de funciones en tiempo de ejecución.
Para entender mejor: cuando llamamos a una función generalmente se causa una cierta sobrecarga (apilamiento, argumentos, saltos, etc...) y, por lo tanto, para funciones muy cortas; suele ser mucho más eficiente insertar el código de la función exactamente donde se llama a la función en lugar pues de realizar el proceso de llamar a la función de manera formal. 
Para esto pues es que aparece el especificador inline el cual lo que hace es informar al compilador: que la extensión inline es preferible en lugar del mecanismo de llamada de función habitual específica. Esto no cambia para nada el comportamiento de una función, sino simplemente es utilizado para SUGERIR al compilador que el código generado por el cuerpo de  la función debería insertarse en cada punto de la función donde es llamada, en lugar de invocarse con una llamada regular a esta función. Por ejemplo, la función concatenate puede declararse inline como:
inline string concatenate (const string& a, const string& b)
{
   return a+b;
}
Esto informa al compilador que cuando se llama a concatenate, el programa prefiere que la función se expanda alineada inline, en lugar de realizar una llamada regular.
Pero tenga en cuenta que la mayoría de los compiladores ya optimizan el código para generar funciones alineadas inline cuando observa una oportunidad que también mejora la eficiencia. Por lo tanto, este especificador simplemente indica al compilador que se prefiere alineadamente inline esta función, aunque el compilador es libre de no alinearlas y optimizarlas al contrario. En C++, la optimización es una tarea delegada al copilador, que es libre de generar cualquier tipo decódigo siempre y cuando el comportamiiento rersultante sea el especificado por el código.


Un tema no menos 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.





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.

El Valor "return" de main

Usted puede haber notado que el tipo de retorno de main es int, pero la mayoría de los ejemplos en este capítulo no retornó ningún valor desde main.
Bueno, hay un inconveniente: si la ejecución de main termina normalmente sin encontrar una declaración de retorno return, el compilador deduce que la función termina con una declaración de devolución implícita.
return 0;
Cuando main devuelve cero (explicita o implícitamente), el retorno lo interpreta como que el programa finalizó correctanente. Otros valores pueden ser devueltos por main, y algunos entornos dan acceso a ese valor a la persona que llama de alguna manera aunque este comportamiento no es necesariamente portátil entre las plataformas. Estos valores para main que están organizados para ser interpretados de la misma manera en todas las plataformas son: 
Valor    Descripción
0    
       El programa tuvo Éxito.
EXIT_SUCCESS   
       El programa tuvo Éxito.
  El valor esta definido en el encabezado<cstdlib>.
EXIT_FAILURE    
       El programa falló.
Este valor esta definido en el encabezado<cstdlib>.
Por que el implícito return 0 para la declaración main es una excepción engañosa, algunos autores consideran que es una buena practica escribir explicitamente el enunciado.



Bueno ahora estamos preparados para practicar bien con ejemplos creados por nosotros mismos. Los invito a visitar algunos ejemplos que he creado para iniciantes. Voy a subirlos en breve y por este blog estaré postando; no descuiden su practica para fijar conocimientos bastante importantes como este!
Con la tecnología de Blogger.