(Java) Subrutinas: procedimientos y funciones - 1


Una subrutina es una parte separada del programa que tiene un nombre y resuelve su propia tarea separada. La subrutina se encuentra al comienzo del programa principal y se puede iniciar (llamar) desde el programa principal especificando el nombre

El uso de subrutinas le permite evitar la duplicación de código, en caso de que necesite escribir el mismo código en diferentes lugares del programa. 
Las bibliotecas que se importan al programa (por ejemplo, la biblioteca matemática Math) consisten en subrutinas que ya han sido compiladas por alguien. Los programadores no necesitan pensar en qué algoritmos implementarán, sino simplemente aplicarlos, pensando solo en lo que están haciendo exactamente. Este es un gran ahorro de tiempo. No es necesario escribir un algoritmo que ya haya sido escrito por otra persona.

Cada rutina solo debe hacer una tarea,  simplemente calcule algo, genere algunos datos o haga otra cosa. 

Hay dos tipos de subrutinas: procedimientos y funciones

Los subprocedimientos realizan algunas acciones, por ejemplo, muestran el resultado en la pantalla de cierta forma (un ejemplo simple, el operador println()  es un subprocedimiento estándar que imprime información en el pantalla)

Las subrutinas de función devuelven un resultado (número, cadena de caracteres, etc.) que podemos usar en el programa principal.

Tratemos de escribir un procedimiento simple:
Supongamos que necesitamos mostrar la cadena "Error" en la pantalla cada vez que puede ocurrir un error en el código por culpa del usuario (por ejemplo, cuando ingresa datos incorrectos)
Esto se puede hacer escribiendo la declaración System.out.println("Error"); Y ahora imagine que esa línea debe insertarse en muchos lugares del programa. Por supuesto, puedes escribirlo en todas partes. Pero esta solución tiene dos inconvenientes.
1) esta cadena se almacenará en la memoria muchas veces
2) si queremos cambiar la salida en caso de error, tendremos que cambiar esta línea en todo el programa, lo cual es bastante inconveniente

Para tales casos, se necesitan procedimientos.
Un programa con un procedimiento podría verse así: ... static void printError() // descripción del procedimiento { System.out.println("Error"); // cuerpo del procedimiento: comandos que ejecutará el procedimiento } public static void main(String[] args) { ... printError() // inicia el procedimiento para su ejecución. Solo especificamos el nombre del procedimiento que queremos ejecutar. ... imprimirError() ... } El procedimiento comienza con la palabra void. Hay corchetes vacíos después del nombre del procedimiento.
Todas las sentencias que se ejecutan en un procedimiento están sangradas. 

Los procedimientos se escriben antes de la función principal main()

Para ejecutar un procedimiento, en el programa principal debe llamarlo por su nombre y recordar escribir paréntesis!
Puede llamar a un procedimiento en un programa cualquier número de veces.

Ahora imaginemos que necesitamos mostrar diferentes mensajes en respuesta al error de un usuario, dependiendo del tipo de error que haya cometido.
En este caso, puede escribir su propio procedimiento para cada error:   vacío estático printErrorZero() { System.out.println("Error. ¡División por cero!"); } Vacío estático printErrorInput() { System.out.println("¡Error en la entrada!"); } ¿Qué pasa si hay muchos más errores posibles? ¡Esta solución no nos conviene!
Necesitamos aprender a controlar el procedimiento diciéndole qué mensaje de error mostrar.
Para hacer esto, necesitamos parámetros que escribiremos entre paréntesis después del nombre del procedimiento error de impresión vacío estático (String s) { System.out.println(s); } En este procedimiento, s es un parámetro, una variable especial que le permite controlar el procedimiento.
El parámetro es una variable que determina cómo funciona la subrutina. Los nombres de los parámetros se enumeran separados por comas en el encabezado del subprograma. El tipo de parámetro se escribe antes del parámetro.

Ahora, al llamar al procedimiento, debe indicar entre paréntesis el valor real que se le asignará al parámetro (variable s) dentro de nuestro procedimiento printError("¡Error! ¡División por cero!"); Este valor se llama argumento.
El argumento es el valor del parámetro que se pasa a la subrutina cuando se llama.
Un argumento puede ser no solo un valor constante, sino también una variable o una expresión aritmética.

A menudo es necesario utilizar variables adicionales que solo se utilizarán en la subrutina. Estas variables se denominan locales (o locales) y solo se pueden manipular dentro de la subrutina en la que se crean.
 
Ámbito de variable local es el bloque entre corchetes dentro del cual se declara

El programa principal en Java también es una subrutina, por lo que todas las variables declaradas dentro de main() son variables locales 
Otras subrutinas no "saben" nada acerca de las variables locales de otras subrutinas.

Así, es posible limitar el alcance (scope) de una variable solo a la subrutina donde realmente se necesita. En programación, esta técnica se denomina encapsulación  - ocultar una variable para que no se modifique desde el exterior.

Si es necesario declarar una variable que sería visible en cualquier parte del programa (en cualquier subrutina), dichas variables se declaran fuera de todas las subrutinas (consulte el programa 3 de la tabla a continuación)
Estas variables se denominan globales.

En Java, cuando se inicia el programa, todas las variables globales se establecen automáticamente en cero (las variables booleanas se vuelven falsas)


Analice tres programas:

1) En este programa, la variable i es local. Una variable local se declara dentro de una subrutina 2) Aquí, aunque haya una variable i en el programa principal (con valor 7), se creará una nueva variable local i con valor 5. 
Cuando ejecute este programa, la pantalla mostrará el valor 75
3) Este programa tiene una variable global i. Su valor se puede cambiar dentro de una subrutina, y dentro del programa principal
El procedimiento trabajará con la variable global i y se le asignará un nuevo valor igual a 2. Se muestra en pantalla el valor 2
prueba de vacío estático () {   int i = 5; Sistema.out.println(i); } prueba de vacío estático () {   int i = 5;   Sistema.out.println(i); } public static void main(String[] args) { { int i = 7;   Sistema.out.println(i);   prueba(); } clase pública Principal { ent yo; prueba de vacío estático () {   yo = 2; } public static void main(String[] args) { { prueba(); Sistema.out.println(i); }