DECLARACIÓN Y DEFINICIÓN DE FUNCIONES
En C++ hay que distinguir entre lo que es un declaración y una definición de una función. En la declaración de una función tan sólo se incluye la cabecera o prototipo de la misma, y siempre tiene que aparecer antes de ser utilizada. En la definición de la función aparecen las sentencias que ejecuta dicha función, y puede aparecer en cualquier parte del programa. Se puede realizar la declaración y la definición al mismo tiempo, pero como veremos más adelante, no es una práctica habitual.
La declaración de una función tiene la siguiente sintaxis:
tipo_devuelto nombre_función (parámetros);
Y la mejor manera de verlo es con un ejemplo:
float integral(float , float);
Ésta sería la declaración o prototipo de una función llamada que que devolverá un tipo real y a su vez tomará como parámetros dos reales, en la declaración no es necesario indicar como se llaman.
Cuando no queremos que una función nos devuelva un valor o que tenga parámetros, utilizaremos el tipo void. Es decir, una función que no devolviera nada y no tomara parámetros se declararía de la siguiente manera:
void ejemplo (void);
Si bien, en la mayoría de los compiladores podríamos prescindir de ello poniendo en la declaración simplemente:
ejemplo ( );
Las funciones, al igual que las variable, admiten el tipo de almacenamiento extern, quiere decir esto, que las podríamos definir en un archivo en utilizarlas en otro sin más que utilizar la palabra reservada extern en su declaración.
Es siguiente paso será definir la función, para ello repetimos el prototipo de la función (en este caso si es necesario introducir el nombre de los parámetros) y a continuación y entre llaves el cuerpo de la misma, en el que podremos utilizar todo lo visto hasta ahora (declaración de variables, bucles, sentencias de control de la lógica, etc.) La manera de utilizar variables o llamar a otras funciones sigue la misma lógica que en turbo pascal, Podremos utilizar variables globales o variables locales definidas en la función, y podremos llamar a todas la funciones que haya sido previamente declaradas (ojo no es necesario que hayan sido definidas).
El valor que devuelve la función lo indicaremos en el cuerpo de la misma con la palabra reservada return valor;
Veamos un programa ejemplo que aplique todo esto:

LA FUNCIÓN MAIN
Todos los programas en C++ tienen un punto de entrada al programa denominado main(). Esto quiere decir, que cuando compilamos un programa y lo ejecutamos, el programa buscará el conjunto de órdenes que vienen dadas pos las sentencias de la función main(), y por lo tanto está será imprescindible en cualquier programa escrito en C++.
Para nosotros de momento la función main no tomará parámetros ni devolverá nada, por lo que su cabecera será void main(void).
ARGUMENTOS POR OMISIÓN EN UNA FUNCIÓN
Todos los parámetros formales de una función, o bien algunos de ellos (desde un determinado parámetro hasta el final), se pueden declarar por omisión. Es decir en la declaración de la función o en su definición se especificarán los valores que deberían asumir los parámetros cuando se produzca una llamada a la función y se omitan los mismos para tales parámetros. Por ejemplo, imaginemos la función factorial antes utilizada,
int factorial (int a=10) //definimos el valor por defecto de a en 10.
{
...
}
main( )
{
cout<< factorial ( ); } Mostraría por pantalla el factorial de 10, ya que no le hemos pasado ningún parámetro (si le pasásemos alguno, evidentemente calcularía el factorial del parámetro que le pasásemos. FUNCIONES EN LÍNEA
Cuando una función se califica en línea (incline) el compilador tiene la facultad de reemplazar cualquier llamada a la función en el programa fuente, por el cuerpo actual de la función. Quiere decir esto, que el compilador puede tomar la iniciativa de no expandir la función, por ejemplo, por ser demasiado larga.
Con esto conseguimos que el compilador inserte el código de la función compilada en el ejecutable cada vez que la llamemos. Si la función se utiliza, por ejemplo diez veces, entonces el código de esa función aparece en el programa diez veces, en lugar de sólo una vez, como es el caso de una función estándar. Esta propiedad de C++ reduce el tiempo de ejecución de los programas, pero aumenta considerablemente el tamaño de los mismos.
La declaración de las funciones en línea se hace anteponiendo la palabra inline.
inline int factorial (int a)
Las funciones en línea si que deben haber sido definidas antes de su utilización.
FUNCIONES SOBRECARGADAS
La sobrecarga de funciones es una característica de C++ que hace los programas más legibles. Consiste en que un conjunto de funciones que realizan la misma tarea o una tarea muy similar tengan el mismo nombre, que tal manera que en función de los parámetros que le pasemos el compilador sepa en cada momento cual de ellas debe utilizar.
Por ejemplo, supongamos una función llamada suma, esta deberá ser diferente si queremos sumar complejos, de otra en la que queramos sumar enteros, pues bien, en C++ se pueden utilizar dos funciones llamadas suma como sigue...
typedef complejo int[2]
int suma (int a, int b)
{
return (a+b)
}
complejo suma (complejo a, complejo b)
{
complejo aux;
aux[1]=a[1] + b[1];
aux[2]=a[2]+b[2];
return aux;
}
Hemos definido un tipo de dato que será complejo formado por un vector de dos elementos, entonces, si al llamar a la función, le pasamos como parámetros dos enteros nos ejecutará el cuerpo de la función que hemos definido primero y en caso de que le pasemos dos variables de tipo complejo ejecutará la segunda.
Todas las posibilidades que hemos visto hasta ahora de TRABAJAR con funciones, obviamente se pueden mezclar unas con otras, es decir podríamos definir perfectamente dos funciones sobrecargadas que tomarán parámetros por defecto.
Tipos de funciones en C++
Los tipos de funciones en c++ son 4, aunque en realidad son las combinaciones de las 2 cosas que una función puede hacer. Si andan perdidos en cuanto a funciones les recomiendo leer mi post anterior: Funciones en C++.
Una función, como les decía, puede hacer (o no) dos cosas: 1 – Recibir datos y 2 – Retornar datos. De esto surgen los cuatro tipos de funciones:
No reciben ni retornan
Reciben y no retornan
No reciben y retornan
Reciben y retornan
Vamos a hacer un programa que sume dos números, usando los cuatro tipos de funciones:
No reciben ni retornan
Las más sencillas. Para usarlas sólo tenemos que saber cómo crearlas y cómo llamarlas. Una función se crea de esta forma general:
tipo nombre(){}
El ‘tipo’ se refiere al tipo de dato (int, float, void, char) y en las funciones que no retornan siempre es void.
El ‘nombre’ es el nombre de la función: cualquiera que empiece con una letra, que sea significativo y que no sea una palabra reservada.
Para llamarlas sólo hay que escribir el nombre de la función seguido de sus paréntesis y un punto y coma (;).
nombre();
Así nuestro programa sería:

Como ven, todo lo que habríamos puesto en nuestro main mejor los pusimos en una función y desde el main la llamamos. Una función siempre, siempre, siempre tiene que ir antes del main.
Una función de este tipo que hemos usado muchas veces es getch();
Reciben y No Retornan
¿Cómo haríamos para pedir los dos números en el main y que la función haga la suma? Para eso tenemos que hacer una función capaz de recibir datos, entonces la sintaxis cambia un poco:
tipo nombre(tipo_var1 nombre_var1, tipo_var2 nombre_var2){}
‘tipo’ y ‘nombre’ se refieren a lo mismo y como no retorna el tipo siempre es void.
Dentro del paréntesis tenemos otros aspectos:
‘tipo_var1’ se refiere al tipo de la variable que nuestra función va a recibir.
‘nombre_var1’ se refiere al nombre de esa variable.
Si queremos recibir una variable hasta ahí es suficiente, si queremos otra variable ponemos una coma (,) y declaramos la siguiente variable.
Para llamar la función hay que poner la variables que vamos a enviar dentro del paréntesis en el mismo orden en que las declaramos en la función:
nombre(var1, var2);
Nuestro programa quedaría así:

Pedimos los dos números en el main, los enviamos a la función, ésta los suma y los muestra.
Una función de este tipo que hemos usado muchas veces es el odiado por muchos, amados por otros, gotoxy(x,y);
Retornan y No Reciben
¿Y si ahora queremos lo contrario? Pedir los números en la función, pero mostrar el resultado en el main. Para eso necesitamos una función que retorne.
Recibir es enviar datos del main a la función. Retornar es enviar datos de la función al main. Para retornar datos hay que hacer dos cosas: no usar void como tipo y usar return.
De forma general:
tipo nombre() { return var; }
El ‘tipo’ tiene que ser del tipo de variable que queremos retornar, si nuestra variable retorna una variable int, pues el tipo de la función es int.
Para indicar qué variable estamos retornando usaremos la palabra return seguido de la variable. Usualmente esto va al final de la función.
Para llamar a la función hay que preparar un colchón en donde caiga la variable que está retornando.
var = nombre();
La variable que está retornando nuestra función se va a almacenar en la variable ‘var’. Este es un buen momento para recordarles que las variables declaradas entre dos llaves {} únicamente existen entre esas dos llaves. O sea que la variable ‘var’ de la función no es la misma que la variable ‘var’ de la función; sin embargo la var del main está adquiriendo el valor de la var del main. Un poco confuso lo se, no se preocupen.
Nuestro programa quedaría así:

Reciben y Retornan
Ahora queremos que nuestra función únicamente sume, el main se va a encargar de pedir los números y sumar los resultados. Para eso necesitamos que nuestra función reciba las variables y además retorne el resultado. ¡Wow! ¿Es acaso eso posible? Claro que sí.
Es sólo cuestión de combinar las funciones que reciben y no retornan con las que retornan y no reciben.
Nuestro programa quedaría así:

Las funciones de la librería math.h son en su mayoría de este tipo. sqrt(); pow(); sin();
En principio puede parecer que las funciones sirven únicamente para organizar el código, lo cual es cierto, pero no sólo eso. ¿Se imaginan si tuviéramos que escribir todo el código detrás de un simple gotoxy();? Ah verdad…
Bueno, no me iba a quedar tranquilo si no les mostraba la versión optimizada de la última función:

No hay comentarios:
Publicar un comentario