FUNCIONES

Concepto de función


Una función es una estructura con un conjunto de instrucciones para realizar una tarea especifica.

Dicho así parece ser que una función se diferencia poco de un trozo de código. Y esto seria así de no ser porque este trozo de código se encierra dentro de una estructura, y por lo tanto esta aislado del resto del código. Por otra parte este trozo de código realiza una tarea especifica dentro del programa.

La función es por lo tanto una parte del código, separada del código principal, y englobada dentro de una estructura. Para diferenciarla del resto del código, esta suele escribirse fuera del mismo, bien sea delante o detrás, y hay que ponerle un nombre.

Cada vez que desde el código principal queremos ejecutar el código de la función, deberemos indicar en el código principal que queremos ejecutar la función, esto es "llamar" o "invocar" a la función.

La función puede tener varios valores de entrada, y uno de salida. Los valores de entrada se llaman parámetros o argumentos, y suelen ser variables que le pasamos para que trabaje con ellas. El valor de salida se llama retorno, y es normalmente un resultado en forma de variable que vuelve al flujo del programa.

Por ejemplo, si queremos hacer una función que sume dos números y nos da su resultado, los parámetros serán los dos números que queremos sumar, y que introducimos en la función; el retorno sera el resultado de la suma de los dos números que devolvemos al flujo normal del programa.

Lar funciones son re utilizables, es decir, podemos llamar a la misma función tantas veces como lo necesitemos, y esta hará su trabajo cada vez que se le llame.

Definir una función

Definir una función es crearla a partir del código fuente. Para ello al principio del programa, después de la linea using namespace std; y antes del cuerpo del mismo definido por int main() { ...} escribiremos la definición de la función:

float suma(float a, float b) {     float c = a + b;     return c; }

La función anterior toma como parámetros dos números reales y devuelve la suma de los mismos. Veamos la sintaxis usada para su definición:

  • Especificadores : float . Escribimos el tipo de valor que debe devolver la función, este es el especificador de tipo, es cecir, int, char, , etc. De no ponerlo se entiende que es int. Delante de este puede poner también un expecificador opcional de tipo de almacenamiento que admite los valores extern o static. De no ponerlo se entiende que usamos extern e indica que la función tiene un uso externo y puede usarse fuera de la pagina en la que fue creada. Si pones static la función solo podrá usarse en la pagina en la que fue creada.
  • Nombre : suma . Es el nombre que le damos a la función. Podemos poner cualquier nombre siempre que no sea una palabra reservada, ni usemos la misma palabra para nombrar otra función u otra variable. Conviene poner nombres significativos que nos recuerden cual es la tarea de la función.
  • Parametros o argumentos : (float a, float b) . Entre paréntesis escribiremos los valores de entrada o parámetros. Estos van siempre separados por comas. Indicaremos siempre el tipo de valor que queremos pasar (int, float, char) seguido de un nombre de variable, es decir para cada parámetro declaramos la variable en la que se va a almacenar dentro de la función. El numero de argumentos que puede tener una función puede ser 0, 1, varios. Caso de tener 0 parámetros, también escribiremos los paréntesis sin nada dentro () .
  • Cuerpo : { .... } . Es el código que debe ejecutarse da vez que se llama a la función. Esta encerrado entre llaves y puede incluir todas las sentencias y estructuras de control que se necesiten.
  • Retorno : return c; La instrucción return seguida del valor de retorno va siempre al final del cuerpo, y es la que hace que el valor indicado sea devuelto al flujo principal del programa. No es necesario que una función tenga retorno, ya que a veces no queremos que la función retorne algo, sino que ejecute directamente las instrucciones.

Veamos como puede quedar el código. incluimos la función en el código, pero dejamos todavía el cuerpo del programa int main () { .. sin rellenar:

1 2 3 4 5 6 7 8 9 10 11

#include using namespace std; 
float suma(float a, float b) {    float c = a + b;    return c; }
 int main (){   //....(sin rellenar)}

Llamada a la función

Una vez hemos definido una función, para que esta haga algo debemos llamarla o invocarla desde el código principal. Es decir, desde el código principal del programa damos la orden para que esta realice su tarea. A esto se le llama "invocar" o "llamar" a una función.

Por lo tanto, para llamar a una función, esta debe estar definida previamente, y el programa debe localizarla, es por eso que la definición de la función debe ir delante del int main () { ....

Para llamar a la función simplemente escribimos su nombre seguida de los argumentos que le queremos pasar entre paréntesis. Aunque podemos utilizar los términos parámetro o argumento indistintamente, es preferible llamar parámetro al que ponemos en la definición o en la declaración de la función, mientras que llamamos argumentos a los valores que pasamos a la función al llamarla.

Si queremos obtener el valor de retorno recogemos este en una variable. En el ejemplo anterior lo haremos de la siguiente manera: dentro del int main() { } escribiremos:

    float n1 = 5.5, n2 = 3.2, n3;    n3 = suma (n1, n2);

En la primera linea definimos tres variables de números reales. Las dos primeras serán los argumentos que pasamos a la función, y la tercera sera la variable donde recogemos el retorno.


La segunda linea es la llamada a la función, para ello escribimos el nombre y entre paréntesis las variables con los valores de los argumentos. estas no tienen que llamarse igual que en la definición, ya que lo que importa es el orden en que las escribamos. Por ejemplo aquí la variable n1 se convertirá en la variable a dentro de la función, y la variable n2 en la variable b.

Lo mismo ocurre con el retorno. este sera guardado dentro de la variable n3, a pesar de que dentro de la función la variable que lo envía es la variable c.

Por ultimo, para comprobar que el ejemplo funciona pondremos una linea debajo de las anteriores que nos saque el resultado en pantalla:

    cout << n3 << endl;

Ahora al compilar y ejecutar el ejemplo nos dará como resultado, que se nos abre la consola y nos muestra la suma de los dos números anteriores (8.7). Con eso sabremos que el programa, con su función, funciona correctamente.

Archivo de ejemplo

Vamos a mejorar el ejemplo anterior, de manera que los números que sumemos se los vamos a pedir al usuario. El código sera el siguiente:

PRUEBA TU MISMO!!! http://cpp.sh/5waum

Tras compilar y ejecutar el archivo, Este le pide al usuario dos números, los cuales son enviados a la función que nos devuelve el resultado de la suma. Después mostramos este resultado en pantalla.

En el código anterior, la definición de la función este entre las lineas 4 y 7. En la linea 15 llamamos a la función.

Podrías decir que en este caso hubiera sido mas fácil hacer la suma directamente, sin tener que utilizar ninguna función. Esto es así para este caso donde tratábamos de poner un ejemplo sencillo para ver el funcionamiento de una función; sin embargo para casos mas complejos, o en los que tengamos que reutilizar el mismo código mas de una vez y en distintos puntos del programa, las funciones pueden ser muy útiles.





Tipos de funciones

Llamada a la función


La llamada a una función es lo que permite ejecutar el contenido de la misma en el programa. Ya hemos visto en la pagina anterior como hacer la llamada a una función. Sin embargo el programa acta de manera secuencial, por lo que cuando llamamos a una función, el programa debe haberla encontrado previamente. Es decir la definición de la función debe ser leída por el programa antes de su llamada.

Si el programa llama a una función antes de leer su definición, sencillamente no la encuentra, y se produce un error de compilación.

Es por esto por lo que la función que hemos hecho de ejemplo en la pagina anterior la tenemos que poner siempre antes del cuerpo del programa (bloque int main() ..).

Pero no siempre nos viene bien tener las funciones delante del cuerpo del programa, ya sea por tener el código mas claro, o por aprovechar otras funciones que tenemos en otras partes del programa, o incluso en otros archivos. Para ello se puede definir la función en otra parte del programa, por ejemplo, después del cuerpo principal, y poner una referencia a la misma antes del mismo.

Partes del programa

Tal como estamos estructurando el archivo en el que guardamos el programa, este constara de tres partes:

  • Primera parte: cabeceras. Estas son las lineas que empiezan por *include en las que hacemos referencia a librerías. Las lineas donde incluimos espacios de nombre (empiezan por using namespace) , y lineas que leen otras partes del programa, tales como funciones, antes de empezar a ejecutar el cuerpo principal.
  • Segunda parte: cuerpo principal. El cuerpo principal del programa esta formado por el bloque int main() { /*sentencias*/ } . Fíjate que este bloque es una función en si misma. Es la función principal que ejecuta todo el programa, dentro de la cual vamos llamando al resto de funciones.
  • Tercera parte: definiciones. Después del bloque principal incluimos las definiciones de las funciones y de otros elementos complejos. estos elementos deben estar declarados en las cabeceras para poder ser utilizados en el cuerpo del programa.

Declarar una función

Para declarar una función pondremos en la cabecera, después de la o las lineas de espacio de nombres, la declaración de la función. esta consiste en escribir el principio de la función igual que en la definición, es decir, escribimos todo excepto el cuerpo de la misma (excepto el contenido entre llaves), y la acabamos con un punto y coma. Por ejemplo, la función de ejemplo de la pagina anterior tendrá la siguiente linea de declaratorio:

float suma (float a, float b);

A la declaración de la función también se le llama prototipo.

Ahora vamos a reescribir el código del ejemplo indicado cambiando la función. Ponemos la declaración al principio y la definición al final, y este quedara así:

PRUEBA TU MISMO!!! http://cpp.sh/5jtgi

El resultado del programa no varia, pero la definición de la función no tiene porque estar ocupando un lugar en el programa antes del cuerpo principal. esta la ponemos al final, y al principio solo dejamos una linea para la declaración de la función.





La función main

Como hemos dicho antes el cuerpo principal del programa esta definido por el bloque int main() { }. Este bloque es también una función, la función "main" o "principal".

La función main es la única que es imprescindible para el funcionamiento del programa, ya que es la única que va a leer el compilador. Todas las demás funciones tienen que ser llamadas desde esta para poder ser ejecutadas en el programa.

Esta función principal es de tipo int, esto quiere decir que deberíamos ponerle un valor de retorno, de hecho, muchos programadores acaban la función con la linea return 0;. Sin embargo no es necesario escribir la linea de retorno, ya que el programa automáticamente, al encontrar el corchete final, presupone que hay un return 0.

La función main es especial, ya que debe aparecer siempre en cualquier programa, ademas no se le puede llamar o invocar desde ninguna parte del programa ni necesita ser declarada. El compilador la entiende directamente, en principio no necesita argumentos y es la única en el que el valor de retorno se le presupone.

Funciones predefinidas

Al incluir una librería en la cabecera del programa (por ejemplo la linea #include),  la librería suele incluir algunas funciones que realizan tareas comunes, a esta funciones solo hay que llamarlas o invocarlas desde el programa para que realicen su tarea, ya que su definición esto ya implícita en la librería.

Ya hemos visto alguna de estas funciones, como la función getline(cin,nombre) que permite escribir cadenas con varias palabras. Otras funciones predefinidas que hemos visto son las que nos permiten hacer la conversión de tipos (por ejemplo char c = char(90);.

Funciones sin retorno

Tanto para declarar como para definir una función escribimos primero el tipo el especificador del tipo de valor que debe devolver (int, float, char ... ), y después el nombre de la función. Sin embargo puede haber funciones que no devuelvan nada, como por ejemplo una función que se limite a escribir un texto o resultado en pantalla. Para este caso tenemos el especificador de tipo void.

Veamos la siguiente definición de una función que se limita a imprimir un texto en pantalla.

void escribeTexto() {     cout << "Esto es una funcion" << endl; }

Esta función no tiene retorno y por lo tanto es una función de tipo void; void significa "vació" o "nada". La función no tiene ningún tipo de retorno, aunque podríamos poner una ultima linea con un return; sin ningún valor, y el programa sigue estando bien escrito.

En el ejemplo que hemos puesto la función no tiene argumentos, es por eso por lo que escribimos los paréntesis vacíos, sin nada dentro, esto también lo podemos expresar escribiendo un void dentro del paréntesis. Después de lo visto aquí, vemos que la función anterior también la podríamos haber definido así:

void escribeTexto(void) {     cout << "Esto es una función" << endl;     return; }

Aunque el ejemplo que hemos puesto aquí es una función sin argumentos, las funciones sin retorno pueden tener argumentos perfectamente, por ejemplo, puede haber una función que recibe dos números y saca el resultado de la suma en pantalla.

Veamos ahora un ejemplo de programa con una función sin retorno, la cual toma el control del programa, dentro de la función, se piden dos números al usuario y los multiplica.

PRUEBA TU MISMO!!! http://cpp.sh/52gxc


Como en cualquier funcion, hemos puesto la declaracion en la cabecera del programa, y la definicion al final del mismo.

Observa como aqui la funcion es la que realiza todas las tareas del programa, limitandose la funcion principal o main a llamarla.



Pasar argumentos

Pasar argumentos por valor


Existen varias formas de pasar un argumento o parámetro a una función. La primera es la que hemos visto hasta ahora, y es pasar los argumentos por valor.

Su principal característica es que el vlor que pasamos a la función no se modifica fuera de la función, aunque lo modifiquemos dentro de la misma. Es decir, al pasar un valor a una función, lo que realmente estamos pasando es una copia del mismo, de manera que el original se conserva tal como estaba.

La forma de pasar argumentos por valor es la vista hasta ahora. Veamos un ejemplo en el que comprobamos que esto es así:

PRUEBA TU MISMO!!!  http://cpp.sh/7bgeb

Este programa nos muestra el valor inicial de una variable. Tras pasarla a un programa en el que sumamos uno, mostramos el valor que devuelve la función, para después volver a mostrar el valor de la variable.

Vemos como el valor de la variable, si bien cambia dentro de la función, tras aplicar la función sigue siendo el mismo.


Pasar argumentos por defecto

Aquí al declarar la función indicamos los valores por defecto que tendrán los argumentos en caso de que al ser llamada no se le pasen.

Para ello en la declaración de la función tenemos que dar un valor a los parámetros, por ejemplo:

int multiplica(int n1=1,int n2=1);

Después en la definicion no debemos indicar los valores por defecto, a no ser que no pongamos declaración y pongamos la definición directamente en la cabecera.

int multiplica(int n1,int n2) { /*sentencias*/ };

Observa como al definir el parámetro, ademas de indicar el tipo, le asignamos un valor por defecto mediante el signo igual. Si al llamar a la función no se han indicado los argumentos, tomara los valores que hemos puesto por defecto. Veamos el siguiente programa de ejemplo:

   PRUEBA TU MISMO!!! http://cpp.sh/7f4rz

La función multiplica dos números, pero si no se le pasan los argumentos estos números serán el 1. En el programa llamamos varias veces a la función, poniendo, 0, 1, y 2 argumentos.

Observa como cuando faltan argumentos en la llamada, la función toma los valores por defecto que hemos puesto en la definición de los parámetros.

Los valores por defecto solo se indican en la declaración (linea 3), de manera que en la definición (lineas 13 a 15) se indican los parámetros sin asignarles un valor.

Por otra parte los argumentos siguen estando definidos por valor, es decir, después de ejecutar la función, los valores que hemos pasado no cambian aunque cambien dentro de la función.



Pasar argumentos por referencia

Al pasar un argumento por referencia lo que hacemos es pasar la propia variable y no una copia de la misma, por lo que todos los cambios que se produzcan en el parámetro que hemos pasado se producen en la variable. Al salir de la función, las variables que hemos modificado dentro de la función estarán también modificadas fuera.

Para pasar una variable por referencia, tanto en la declaración como en la definición, al escribir las variables que contienen los parámetros debes ponerles el signo ampersand & delante. Veamos el ejemplo:

int sumauno(int &a);

Aquí en el parámetro le hemos puesto delante el signo de ampersand, lo mismo debemos hacer en la definición de la función:

int sumauno(int &a) { */sentencias*/ }

Para ver la diferencia entre pasar los parámetros por valor o por referencia, vamos a coger el primer ejemplo que hemos puesto, en el que pasábamos los parámetros por valor, y los cambiamos a parámetros por referencia. El programa quedara así:


PRUEBA TU MISMO!!! http://cpp.sh/8uech


La única diferencia entre este programa y el primero es el signo ampersandque hemos puesto para pasar los valores por referencia.

Vemos en el programa como al comprobar el valor de la variable tras ejecutar la función, este ha cambiado, al igual que ha cambiado dentro de la función.

Si pasamos los parámetros por referencia no podemos poner valores por defecto. Los parámetros por defecto solo pueden estar presentes junto con parámetros pasados por valor.

El signo ampersand lo hemos puesto siempre delante de la variable, pero también puede ir detrás de la especificación del tipo, es decir podemos escribir:

int sumauno(int &a);

... o también podemos escribir:

int sumauno(int& a);

Las dos formas son correctas, y el programa compilara igualmente.



 Acciones

Que son las acciones


Las acciones son funciones que no tienen retorno. Es decir, las acciones son todas las funciones de tipo void.

Las llamamos acciones, y las distinguimos del resto de funciones porque este tipo de funciones no tienen retorno y se utilizan para realizar tareas que pueden ser mas o menos comunes dentro del programa, pero no necesitan retornar nada, sino que simplemente realizan su tarea y al acabar vuelven al flujo normal del programa.

Aunque las acciones son funciones que no tienen retorno, esto no es del todo cierto, ya que utilizando el paso de argumentos por referencia, se pueden crear variables que sirvan específicamente para "retornar" valores, tal como veremos mas adelante.

Utilizar acciones

Como hemos indicado, una acción es una función de tipo "void", y que no tiene retorno, simplemente ejecuta las sentencias que tiene y después vuelve al programa principal. Veamos un ejemplo:

PRUEBA TU MISMO!! http://cpp.sh/4ktcj

Es la propia funcion la que realiza el trabajo de devolver el resultado en la pantalla. Observa como al no tener retorno, la funcion es del tipo "void", y al hacer la llamada a la funcion, esta no se le asigna a ninguna variable, y que no hay nada que retornar. 




Retornar por referencia

Supongamos que queremos hacer una funcion parecida a la anterior, pero en lugar de mostrar los resultados en pantalla, nos devuelve los resultados al flujo principal del programa, para despues desde ahi mostrarlos o utilizarlos para otras cosas.

El primer problema que tenemos es el de querer retornar mas de un valor. Una funcin solo puede tener un valor de retorno, por lo que si queremos retornar suma, resta y multiplicacion de dos numeros, una solucion seria utilizar tres funciones, y cada una de ellas retorna un resultado.

Sin embargo la solucion mas comun es pasar tres variables por referencia, en las cuales gurdaremos el valor de las operaciones, veamos el procedimiento:

En el flujo principal del programa, ademas de las dos variables en las que recoremos los numeros que nos da el usuario, declaramos tres variables en las que recogeremos los resultados:

int main (){    int a, b, mult, resta, suma ;    ... }

A continuacion despues de la funcion main escribimos la definicion de la funcion para operar con los numeros:

void operar(int x, int y, int &s, int &:r, int &m) {    m = x*y;    r = x-y;    s = x+y; }

Los dos primeros parametros de la funcion se pasan por valor, y son los numeros con los que operaremos. Los otros tres parametros se pasan por referencia, y modifican las variables que les pasamos para guardar en ellas los resultados.

Observa como en realidad estamos utilizando una accion o funcion tipo void.

Lo siguiente es declarar la funcion en la cabecera del programa. La cabecera del programa sera la siguiente:

#include using namespace std; void operar(int x, int y, int &s, int &r, int &m);

Ahora nos queda completar la funcion principal o main. para ello despues de la linea en la que hemos declarado las variables, escribiremos varias acciones: le pedimos al usuario que escriba dos numeros y los recogemos. Despues llamamos a la funcion:

int main (){    int a, b, mult, resta, suma ;    cout << "Escribe dos numeros : " << endl;    cin >> a >> b;    operar(a, b, suma, resta, mult);    .... }

Ahora solo nos queda mostrar los resultados en pantalla, ya que tras la llamada a la funcion, las variables que hemos pasado por referencia se han modificado y contienen los resultados de las operaciones. Acabamos por tanto de escribir la funcion main la cual quedara asi:

int main (){    int a, b, mult, resta, suma ;    cout << "Escribe dos numeros : " << endl;    cin >> a >> b;    operar(a, b, suma, resta, mult);    cout << "Tus numeros son " << a << " y " << b << endl;    cout << "Suma : " << suma << endl;    cout << "Resta : " << resta << endl;    cout << "Multiplicacion : " << mult << endl; }

Veamos ahora el programa completo, el cual sera el siguiente:

PRUEBA TU MISMO!!! http://cpp.sh/9d5aw


Observa como en realidad lo que hemos hecho mediante la función no es retornar valores, sino modificar las variables que ya teniamos para obtener los valores que calcula la funcion.

El "retorno" de valores por referencia no excluye el poder retornar valores mediante la instruccion return. Podemos usar una funcion normal en la que retornemos un valor mediante la instruccion return y modificar otros valores mediante el paso de valores por referencia.


ESTE SITIO FUE CONSTRUIDO USANDO