Funciones III: más cosas
Aún quedan algunas cosas interesantes por explicar sobre las funciones en C++.
Parámetros con valores por defecto
En algunas funciones suele suceder que para ciertos parámetros se repiten frecuentemente los mismos valores cada vez que necesitamos invocarlas.
Por ejemplo, podemos tener una función que calcule la velocidad final de un cuerpo en caída libre. Para hacer el cálculo necesitaremos algunos parámetros: velocidad inicial, altura...
h = vo·t + 1/2·g·t2
vf = vo + g·t
donde:
h es altura, o espacio recorrido
g es la fuerza de la gravedad, o aceleración
v0 es la velocidad inicial
vf es la velocidad final y
t es el tiempo |
La fuerza de la gravedad también es un parámetro que hay que tener en cuenta, aunque podemos considerar que casi siempre nuestros cálculos se referirán a caídas que tendrán lugar en el planeta Tierra, por lo que podemos estar tentados de considerar la gravedad como una constante. Sin embargo, C++ nos permite tomar una solución intermedia. Podemos hacer que la fuerza de la gravedad sea uno de los parámetros de la función, y darle como valor por defecto el que tiene en la Tierra. De este modo, cuando no proporcionemos un valor para ese parámetro en una llamada, se tomará el valor por defecto, y en caso contrario, se usará el valor proporcionado.
Durante el programa, cuando se llama a la función incluyendo valores para esos parámetros opcionales, funcionará como cualquiera de las funciones que hemos usado hasta ahora. Pero si se omiten todos o algunos de estos parámetros la función trabajará con los valores por defecto para esos parámetros que hemos definido.
Por ejemplo:
#include <iostream>
#include <cmath>
using namespace std;
double VelocidadFinal(double h, double v0=0.0, double g=9.8);
int main() {
cout << "Velocidad final en caida libre desde 100 metros,n" <<
"partiendo del reposo en la Tierra" <<
VelocidadFinal(100) << "m/s" << endl;
cout << "Velocidad final en caida libre desde 100 metros,n" <<
"con una velocidad inicial de 10m/s en la Tierra" <<
VelocidadFinal(100, 10) << "m/s" << endl;
cout << "Velocidad final en caida libre desde 100 metros,n" <<
"partiendo del reposo en la Luna" <<
VelocidadFinal(100, 0, 1.6) << "m/s" << endl;
cout << "Velocidad final en caida libre desde 100 metros,n" <<
"con una velocidad inical de 10m/s en la Luna" <<
VelocidadFinal(100, 10, 1.6) << "m/s" << endl;
return 0;
}
double VelocidadFinal(double h, double v0, double g) {
double t = (-v0+sqrt(v0*v0 + 2*g*h))/g;
return v0 + g*t;
} |
Nota: En este programa hemos usado la función sqrt. Se trata de una función ANSI C, que está declarada en el fichero de cabecera math, y que, evidentemente, sirve para calcular raíces cuadradas. |
La salida de este programa será:
Velocidad final en caida libre desde 100 metros,
partiendo del reposo en la Tierra 44.2719 m/s
Velocidad final en caida libre desde 100 metros,
con una velocidad inicial de 10m/s en la Tierra 45.3872 m/s
Velocidad final en caida libre desde 100 metros,
partiendo del reposo en la Luna 17.8885 m/s
Velocidad final en caida libre desde 100 metros,
con una velocidad inical de 10m/s en la Luna 20.4939 m/s |
La primera llamada a la función "VelocidadFinal" dará como salida la velocidad final para una caída libre desde 100 metros de altura. Como no hemos indicado ningún valor para la velocidad inicial, se tomará el valor por defecto de 0 m/s. Y como tampoco hemos indicado un valor para la gravedad, se tomará el valor por defecto, correspondiente a la fuerza de la gravedad en la Tierra.
En la segunda llamada hemos indicado explícitamente un valor para el segundo parámetro, dejando sin especificar el tercero. Como en el caso anterior, se tomará el valor por defecto para la fuerza de la gravedad, que es 9.8.
Este método tiene algunas limitaciones, por otra parte, muy lógicas:
-Sólo los últimos argumentos de las funciones pueden tener valores por defecto.
-De estos, sólo los últimos argumentos pueden ser omitidos en una llamada.
-Cada uno de los valores por defecto debe especificarse bien en los prototipos, o bien en las declaraciones, pero no en ambos.
En la tercera y cuarta llamadas hemos tenido que especificar los tres parámetros, a pesar de que en la tercera el valor de la velocidad inicial es cero. Si sólo especificamos dos parámetros, el programa interpretará que el que falta es el último, y no el segundo. El compilador no puede adivinar qué parámetro queremos omitir, por eso es necesario aplicar reglas extrictas.
Cuando se declaren valores de parámetros por defecto en prototipos, no es necesario indicar el nombre de los parámetros.
Por ejemplo:
void funcion(int = 1); // Legal
void funcion1(int a, int b=0, int c=1); // Legal
void funcion2(int a=1, int b, int c); // Ilegal
void funcion3(int, int, int=1); // Legal
...
void funcion3(int a, int b=3, int c) // Legal
{
} |
Los argumentos por defecto empiezan a asignarse empezando por el último.
int funcion1(int a, int b=0, int c=1);
...
funcion1(12, 10); // Legal, el valor para "c" es 1
funcion1(12); // Legal, los valores para "b" y "c" son 0 y 1
funcion1(); // Ilegal, el valor para "a" es obligatorio |
Comentarios