Java para programadores. Devolución de valores

LA SUBRUTINA QUE DEVUELVE VALORES se llama función. Una función determinada, solo puede devolver valores de un tipo concreto, denominado tipo de retorno (return type) de la función. La llamada a una función, normalmente aparece en los lugares en que el ordenador esta esperando encontrarse un valor, como en la parte derecha de una instrucción de asignación, como parámetro en una llamada a subrutina, o en el medio de alguna expresión. Las funciones de valor boleano también pueden ser usadas como condiciones en las instrucciones if, while o do.

También es correcto el emplear una llamada a función en una instrucción como si fuera una subrutina normal. En esta caso, el ordenador ignorará el valor calculado por la subrutina.

Esto a veces tiene sentido. Por ejemplo, la función console.getln(), que devuelve un tipo String, lee y devuelve la línea tecleada por el usuario.

Normalmente esa línea devuelta, es asignada a una variable en una instrucción

String name=console.getln();

para que el programa la emplee mas tarde. Sin embargo, esta función también es útil emplearla como subrutina con la llamada

console.getln();

para que lea y descargue todo lo que se haya tecleado hasta el siguiente retorno de carro.

Ya hemos visto y usado funciones como Math.sqrt() y console.getInt(). Lo que no hemos visto, es como escribirlas nosotros.

La función, en principio tiene la misma forma que una subrutina, excepto que tiene que especificar el valor que se va a devolver. Esto se puede realizar con la instrucción return, que tiene esta forma:

return expresión;

Esta instrucción solo pueden aparecer en el interior de la definición de la función, y el tipo de la expresión debe ser el mismo que el que se ha especificado como tipo de  retorno para esta función. Cuando el ordenador ejecuta la instrucción  return, evalúa la expresión. finaliza la ejecución de la función y usa el valor de la expresión como valor de retorno de la función.

Dentro de un método ordinario, que ha declarado como tipo de retorno “void” puede utilizar la instrucción return para finalizar la ejecución del método inmediatamente y devolver el control al punto del programa que lo invocó, pero esta instrucción return no puede emplear la expresión.

Es una forma bastante usual de finalizar la ejecución de una subrutina, pero no es obligatorio. Por otra parte, en la función si que es obligatorio la instrucción return con la expresión.

Aquí tenemos una función que podemos emplear en el programa que calcula la secuencia 3N+1. Dado un termino de la secuencia, esta función calcula el siguiente:

        static int nextN(int currentN) {
           if (currentN % 2 == 1)     // prueba si N es impar
              return 3*currentN + 1;  // si lo es, devuelve esto
           else
              return currentN / 2;    // si no, devuelve esto
        }

Muchos programadores, entre los que me encuentro, prefieren utilizar una instrucción return única, como final real de la función. Esto permite encontrar la instrucción return mas fácilmente. Podemos escoger el escribir la función de esa forma, en el siguiente ejemplo:

        static int nextN(int currentN) {
           int answer;  // answer sera el valor de retorno
           if (currentN % 2 == 1)    // prueba si N es impar
              answer = 3*currentN+1; // si lo es, prepara esto
           else
              answer = currentN / 2; // si no, prepara esto
           return answer;   // (Devuelve el valor !No lo olvide!)
        }

Aquí esta la subrutina que emplea nuestra función nextN.En este caso, la mejora frente a la versión original, no es muy grande, pero si nextN() fuera una función larga que realizara cálculos complejos, entonces si que habría tenido sentido el ocultar la complejidad dentro de la función:

         static void Print3NSequence(int startingValue) {

            // imprimir la secuencia 3N+1 en la consola usando
            // startingValue como valor inicial de N
            int N = startingValue;  // N es el termino de la secuencia
            int count = 1;   // cuenta el numero de términos

            console.putln("La secuencia 3N+1 empieza en " + N);
            console.putln();
            console.putln(N);  // imprimir el primer termino

            while (N > 1) {
                N = nextN(N);  // calcula siguiente termino
                count++;   // lo cuenta
                console.putln(N);  // lo imprime
            }

            console.putln();
            console.putln("Aquí hay " + count + " términos en la secuencia.");

         }  // end of Print3NSequence()

Aquí tenemos algunos ejemplos mas sobre funciones. El primero calcula la letra que se ha de colocar según una escala de valores numéricos:

       static char letterGrade(int numGrade) {

          // devuelve la letra correspondiente
          // a una escala numérica

          if (numGrade >= 90)
             return 'A';   // 90 o superior devuelve A
          else if (numGrade >= 80)
             return 'B';   // 80 a 89 devuelve B
          else if (numGrade >= 65)
             return 'C';   // 65 a 79 devuelve C
          else if (numGrade >= 50)
             return 'D';   // 50 a 64 devuelve D
          else
             return 'F';   // cualquier otra cosa devuelve F

       }  // end of function letterGrade()

El tipo del valor de retorno de letterGrade() es char. Las funciones pueden devolver cualquier tipo de valor. Aquí tenemos una que devuelve un valor de tipo boolean:

       static boolean isPrime(int N) {

          // devuelve true si N es numero primo, esto es,
          // si N es positivo y no es divisible por ningún
          // numero positivo excepto por 1 y él mismo

          int maxToTry = (int)Math.sqrt(N);
               // probaremos de dividir N por números entre
               // 2 y maxToTry; si N no es divisible por
               // ninguno de esos números, entonces N es primo.
               // (observe que  Math.sqrt(N) devuelve un valor 
               // de tipo double, el valor debe cambiarse a 
               // tipo int antes de poder asignar 
               // a maxToTry.)

           for (int divisor = 2; divisor <= maxToTry; divisor++) {
               if ( N % divisor == 0 )   // prueba si N es divisible
                  return false;  // si lo es, no es primo
           }

           // al llegar a este punto, N debe ser primo. De otra forma
           // la función ya habría terminado al ejecutar
           // la instrucción return en el bucle for.

           return true;  // si, N es primo

        }  // end of function isPrime()

Finalizaré esta sección con la versión completa de programa 3N+1. Esto nos permitirá el emplear la función nextN() en un programa completo.

También tendremos la posibilidad de mejorar el programa definiendo la impresión de los términos de la secuencia en columna, con varios términos en cada línea.

Así haremos la salida mas presentable. La idea es fácil. Tenemos que controlar cuantos términos se ha escrito en la línea actual, cuando el valor alcance un determinado numero, iniciaremos nueva línea.

Para conseguir que los términos aparezcan alineados en columna, usaremos la versión de console.put() con firma put(int,int). El segundo parámetro int indica la anchura de la columna.

Para enseñar otra nueva idea, mi programa especifica el numero de columnas de salida y la anchura de cada columna como constante.

Una constante es como una variable excepto que su valor no puede cambiar nunca mientras el programa este funcionando. (para cambiar el valor, deberá editar el programa y recompilarlo).

Las constantes se emplean en los programas porque es mas fácil recordar y entender un nombre que una constante literal.

En Java, una constante se define utilizando en la declaración de la variable el modificador “final“.

La palabra final, indica que la constante esta en su forma final– que el valor asignado es el final y no puede ser cambiado. Mas adelante, veremos que el modificador final también puede ser usado en la definición de métodos.

      public class ThreeN {

         /*
        Este programa calcula y presenta la secuencia 3N+1
        Empieza la secuencia en donde el usuario indique
        Los términos de la secuencia se imprimen en columnas
        con varios términos en cada línea. Después de finalizar 
        la secuencia, se informa del numero de términos
         */

         final static int numberOfColumns = 5;  // constant indica el
                                     // numero de términos en columna

         final static int columnWidth = 8;  // constant indica anchura
                                            // en numero de caracteres en
                                            // cada columna

         Console console;  // ventana para entrada/salida

         public static void main(String[] args) {

            console = new Console();

            console.putln("Este programa imprime la secuencia 3N+1 ");
            console.putln("empezando en el valor que especifique.");
            console.putln();

            int K = 0;
            do {
               console.putln("Indique valor inicial;");
               console.put("para finalizar programa entre 0: ");
               K = console.getInt();  // lee valor inicial del usuario
               if (K > 0)   // imprime la secuencia si  K is > 0
                  Print3NSequence(K);
            } while (K > 0);   // continua solo si K > 0

            console.close();

         } // end main()

         static void Print3NSequence(int startingValue) {

            // imprime la secuencia 3N+1 en la consola usando
            // startingValue como valor inicial de N

            int N = startingValue;  // N representa el termino.
            int count = 1;   // cuenta el numero de términos.
            int onLine = 1;  // onLine cuenta términos en la línea actual.

            console.putln("La secuencia 3N+1 empieza en " + N);
            console.putln();
            console.put(N, columnWidth);  // imprime el primer termino

            while (N > 1) {
                N = nextN(N);  // calcula siguiente
                count++;   // cuenta el termino
                if (onLine == numberOfColumns) { // si la línea esta llena
                   console.putln();  //imprime retorno de carro
                   onLine = 0;   // y borra contador de términos en línea
                }
                console.put(N, columnWidth);  // imprime el termino
                onLine++;   // incrementa contador de términos en línea
            }

            console.putln();  // final de la línea actual
            console.putln();  // añade línea en blanco
            console.putln("Aquí hay " + count + " términos en la secuencia.");

         }  // end of Print3NSequence()

         static int nextN(int currentN) {
             // calcula el siguiente termino de la secuencia 3N+1
             if (currentN % 2 == 1)
                return 3 * currentN + 1;
             else
                return currentN / 2;
         }  // end of nextN()

      } // end of class ThreeN

 

Acerca de Miguel Garcia

Programador, Desarrollador web, Formador en distintas areas de informatica y director de equipos multidisciplinares.
Esta entrada fue publicada en Formacion, Java y etiquetada , . Guarda el enlace permanente.

Una respuesta a Java para programadores. Devolución de valores

  1. Pingback: Java - Un resumen organizado....o no.Recursos para formacion

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.