AnteriorPosterior

9. Funciones

  Curso: Introducción a Java

9. Contacto con las funciones.

9.1.Descomposición modular

En ocasiones, nuestros programas contendrán operaciones repetitivas. Crear funciones nos ayudará a que dichos programas sean más fáciles de crear y más robustos (con menos errores). Vamos a verlo con un ejemplo...

Imaginemos que queremos calcular la longitud de una circunferencia a partir de su radio, y escribirla en pantalla con dos cifras decimales. No es difícil: por una parte, la longitud de una circunferencia se calcula con 2 * PI * radio; por otra parte, para conservar sólo dos cifras decimales, lo podemos hacer de varias formas, una de las cuales consiste en multiplicar por 100, quedarnos con la parte entera del número y volver a dividir entre 100:

// FuncionesPrevio1.java
// Ejemplo previo 1 de la conveniencia de usar funciones
// para evitar código repetitivo
 
import java.io.*;
 
class FuncionesPrevio1 { 
    public static void main( String args[] ) { 
 
        int radio = 4;
 
        double longCircunf = 2 * 3.1415926535 * radio;
        double longConDosDecimales = 
            Math.round(longCircunf * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio + " es " + longConDosDecimales); 
    } 
} 
 

Su resultado sería

La longitud de la circunferencia de radio 4 es 25.13

Si ahora queremos hacerlo para 5 circunferencias, podemos repetir esa misma estructura varias veces:

// FuncionesPrevio1.java
// Ejemplo previo 2 de la conveniencia de usar funciones
// para evitar código repetitivo
 
import java.io.*;
 
class FuncionesPrevio2 { 
    public static void main( String args[] ) { 
 
        int radio1 = 4;
 
        double longCircunf1 = 2 * 3.1415926535 * radio1;
        double longConDosDecimales1 = 
            Math.round(longCircunf1 * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio1 + " es " + longConDosDecimales1); 
 
        int radio2 = 6;
 
        double longCircunf2 = 2 * 3.1415926535 * radio2;
        double longConDosDecimales2 = 
            Math.round(longCircunf2 * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio2 + " es " + longConDosDecimales2); 
 
        int radio3 = 8;
 
        double longCircunf3 = 2 * 3.1415926535 * radio3;
        double longConDosDecimales3 = 
            Math.round(longCircunf3 * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio3 + " es " + longConDosDecimales3); 
 
        int radio4 = 10;
 
        double longCircunf4 = 2 * 3.1415926535 * radio4;
        double longConDosDecimales4 = 
            Math.round(longCircunf4 * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio4 + " es " + longConDosDecimales4); 
 
        int radio5 = 111;
 
        double longCircunf5 = 2 * 3.1415926535 * radio5;
        double longConDosDecimales5 = 
            Math.round(longCircunf5 * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio5 + " es " + longConDosDecimales5); 
    } 
} 
 

Pero un programa tan repetitivo es muy propenso a errores: tanto si escribimos todo varias veces como si copiamos y pegamos, es fácil que nos equivoquemos en alguna de las operaciones, usando el nombre de una variable que no es la que debería ser. Por ejemplo, podría ocurrir que escribiéramos "double longCircunf5 = 2 * 3.1415926535 * radio4;" (en el último fragmento no aparece "radio5" sino "radio4"). El programa se comportaría de forma incorrecta, y este error podría ser muy difícil de descubrir.

La alternativa es crear una "función": un bloque de programa que tiene un nombre, que recibe ciertos datos, y que puede incluso devolvernos un resultado. Por ejemplo, para el programa anterior, podríamos crear una función llamada "escribirLongCircunf" (escribir la longitud de la circunferencia), que recibiría un dato (el radio, que será un número entero) y dará todos los pasos que daba nuestro primer "main":

public static void escribirLongCircunf( int radio ) { 
    double longCircunf = 2 * 3.1415926535 * radio;
    double longConDosDecimales = 
        Math.round(longCircunf * 100) / 100.0;
    System.out.println( "La longitud de la circunferencia " +
        "de radio " + radio + " es " + longConDosDecimales); 
}

Y desde "main" (el cuerpo del programa) usaríamos esa función tantas veces como quisiéramos:

public static void main( String args[] ) { 
    escribirLongCircunf(4);
    escribirLongCircunf(6);
    ...

De modo que el programa completo quedaría:

// Funciones01.java
// Primer ejemplo de funciones
 
import java.io.*;
 
class Funciones01 { 
 
    public static void escribirLongCircunf( int radio ) { 
        double longCircunf = 2 * 3.1415926535 * radio;
        double longConDosDecimales = 
            Math.round(longCircunf * 100) / 100.0;
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio + " es " + longConDosDecimales); 
    }
 
    public static void main( String args[] ) { 
        escribirLongCircunf(4);
        escribirLongCircunf(6);
        escribirLongCircunf(8);
        escribirLongCircunf(10);
        escribirLongCircunf(111);
    } 
} 
 

Por ahora, hasta que sepamos un poco más, daremos por sentado que todas las funciones tendrán que ser "public" y "static".

Ejercicio propuesto 9.1.1: Crea una función llamada "borrarPantalla", que borre la pantalla dibujando 25 líneas en blanco. No debe devolver ningún valor. Crea también un "main" que permita probarla.

Ejercicio propuesto 9.1.2: Crea una función llamada "dibujarCuadrado3x3", que dibuje un cuadrado formato por 3 filas con 3 asteriscos cada una. Crea también un "main" para comprobar que funciona correctamente.

9.2. Parámetros

Nuestra función "escribirLongCircunf" recibía un dato entre paréntesis, el radio de la circunferencia. Estos datos adicionales se llaman "parámetros", y pueden ser varios, cada uno indicado con su tipo de datos y su nombre.

Ejercicio propuesto 9.2.1: Crea una función que dibuje en pantalla un cuadrado del ancho (y alto) que se indique como parámetro. Completa el programa con un "main" que permita probarla.

Ejercicio propuesto 9.2.2: Crea una función que dibuje en pantalla un rectángulo del ancho y alto que se indiquen como parámetros. Completa el programa con un "main" que permita probarla.

9.3. Valor de retorno

Las funciones "void", como nuestra "escribirLongCircunf" y como el propio cuerpo del programa ("main") son funciones que dan una serie de pasos y no devuelven ningún resultado. Este tipo de funciones se suelen llamar "procedimientos" o "subrutinas".

public static void saludar( ) {         
    System.out.println( "Bienvenido"); 
    System.out.println( "Comenzamos..."); 
}

Por el contrario, las funciones matemáticas suelen dar una serie de pasos y devolver un resultado, por lo que no serán "void", sino "int", "double" o del tipo que corresponda al dato que devuelven. Por ejemplo, podríamos calcular la superficie de un círculo así:

public static double superfCirculo( int radio ) { 
    double superf = 3.1415926535 * radio * radio;
    double superfConDosDecimales = 
        Math.round(superf * 100) / 100.0;
    return superfConDosDecimales;
}

O descomponer la parte matemática del ejemplo anterior (el cálculo de la longitud de la circunferencia) en una función independiente, así:

public static double longCircunf( int radio ) { 
    double longitud = 2 * 3.1415926535 * radio;
    double longConDosDecimales = 
        Math.round(longitud * 100) / 100.0;
    return longConDosDecimales;
}

Y un programa completo quedaría que usara todas esas funciones quedaría:

// Funciones02.java
// Segundo ejemplo de funciones
 
import java.io.*;
 
class Funciones02 { 
 
    public static double longCircunf( int radio ) { 
        double longitud = 2 * 3.1415926535 * radio;
        double longConDosDecimales = 
            Math.round(longitud * 100) / 100.0;
        return longConDosDecimales;
    }
 
    public static double superfCirculo( int radio ) { 
        double superf = 3.1415926535 * radio * radio;
        double superfConDosDecimales = 
            Math.round(superf * 100) / 100.0;
        return superfConDosDecimales;
    }
 
    public static void saludar( ) {         
        System.out.println( "Bienvenido"); 
        System.out.println( "Comenzamos..."); 
    }
 
    public static void escribirLongCircunf( int radio ) {       
        System.out.println( "La longitud de la circunferencia " +
            "de radio " + radio + " es " + longCircunf( radio )); 
    }
 
    public static void main( String args[] ) { 
        saludar();
        escribirLongCircunf(4);
        escribirLongCircunf(6);
        escribirLongCircunf(8);
        escribirLongCircunf(10);
        escribirLongCircunf(111);
        System.out.println( "La superficie del círculo " +
            "de radio 5 es " + superfCirculo(5)); 
    } 
} 
 

Volveremos más adelante a las funciones, para formalizar un poco lo que hemos aprendido, y también para ampliarlo, pero ya tenemos suficiente para empezar a practicar.


Ejercicio propuesto 9.3.1: Crea una función que calcule el cubo de un número real (float) que se indique como parámetro. El resultado deberá ser otro número real. Probar esta función para calcular el cubo de 3.2 y el de 5.

Ejercicio propuesto 9.3.2: Crea una función que calcule el menor de dos números enteros que recibirá como parámetros. El resultado será otro número entero.

Ejercicio propuesto 9.3.3: Crea una función que devuelva la primera letra de una cadena de texto. Probar esta función para calcular la primera letra de la frase "Hola".

Ejercicio propuesto 9.3.4: Crea una función que devuelva la última letra de una cadena de texto. Probar esta función para calcular la última letra de la frase "Hola".

Ejercicio propuesto 9.3.5: Crea una función "esPrimo", que reciba un número y devuelva el valor booleano "true" si es un número primo o "false" en caso contrario.

Actualizado el: 24-07-2015 19:46

AnteriorPosterior