Subrutinas: procedimientos y funciones - 1


Una subrutina es una parte separada de un 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 si necesita escribir el mismo código en diferentes lugares programas . 
Las bibliotecas que se importan a un programa (por ejemplo, Sistema) consisten en rutinas que ya han sido compiladas por alguien. Los programadores no tienen que pensar en qué algoritmos se implementan en ellos, simplemente los aplican, 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 subrutina solo debe hacer una tarea, ya sea calcular algo, generar algunos datos o hacer otra cosa. 

Las subrutinas, o métodos, son de dos tipos:  funciones (aquellas que devuelven el resultado del trabajo) y procedimientos (aquellas que no lo hacen).

Comencemos con el segundo tipo. Intentemos escribir un ejemplo 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
Console.WriteLine("Error"); Ahora imaginemos que esta 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 a lo largo del programa, lo cual es bastante inconveniente.

Para tales casos, se necesitan métodos y procedimientos.
Un programa con un procedimiento podría verse así:

usando System;
programa de clase {
    vacío estático PrintError() {
        Console.WriteLine("Error");
    }
    vacío estático Principal() {
        Error de impresión();
    }
}

 

Un procedimiento comienza con la palabra void. Después de la nombre del procedimiento  se escriben corchetes vacíos.
Todas las sentencias que se ejecutan en un procedimiento están sangradas. 
El modificador Static  significa que el campo, método o propiedad dada no pertenecerá a cada objeto de la clase, sino a todos juntos.
Los métodos y procedimientos se escriben antes que el método principal Main().

Para hacer referencia a un procedimiento, en el programa principal debe llamarlo por su nombre y no olvide 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 a un error del usuario, dependiendo de si exactamente qué error cometió.
En este caso, puede escribir su propio procedimiento para cada error: 

 

void imprimirErrorZero() {     Console.WriteLine("Error. ¡División por cero!"); }

 

 

void printErrorInput() { Console.WriteLine("¡Error en la entrada!"); } ¿Qué pasa si hay muchos más errores posibles? Entonces 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
void printError(string s) { Consola.WriteLine(s); } En este procedimiento, s es un parámetro, una variable especial que permite controlar el procedimiento.
El parámetro es una variable de cuyo valor depende el funcionamiento de 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 especificar el valor real entre paréntesis que se asignará al parámetro (la variable s) dentro de nuestro procedimiento printError("¡Error! ¡División por cero!"); Este valor se denomina argumento.
El argumento es el valor del parámetro que se pasa a la subrutina cuando se llama.
El argumento puede ser no solo un valor constante, sino también una variable o una expresión aritmética.< /span>< /span>

Variables locales y globales
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 C# también es una subrutina, por lo que todas las variables declaradas dentro de void 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 llama encapsulación  - ocultar la variable para que no se cambie desde el exterior.

Si es necesario declarar una variable que sería visible en cualquier lugar 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 C#, cuando se inicia el programa, todas las variables globales se establecen automáticamente en cero (las variables booleanas toman el valor falso).

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 se ejecuta este programa, en la pantalla aparecerá el valor 75.
3) Este programa tiene una variable global i. Su valor se puede cambiar dentro de la 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 el valor 2.
prueba de vacío estático () {   int i = 5; Consola.Escribir("i"); } prueba de vacío estático () {   int i = 5;   Consola.Escribir("i"); } vacío estático principal () { int i = 7;   Consola.Escribir("i");   prueba(); } utilizando el sistema; programa de clase { ent yo; prueba de vacío estático () {   yo = 2; } vacío estático principal () { prueba(); Consola.Escribir("i"); } }
Tarea
Escriba un procedimiento que intercambie los valores de dos variables.

La peculiaridad de esta tarea es que necesitamos que los cambios realizados en el procedimiento sean conocidos por el programa que llama.

Intentemos escribir el procedimiento así: static void Swap (int a, int b) // con tal descripción de los parámetros del procedimiento, { // copiará los valores de los argumentos (x e y) intc; // las variables a y b son variables independientes no relacionadas con x e y c = un; a = b; b=c; } vacío estático principal () { entero x=1, y=2; Intercambiar (x, y); //los valores de las variables x e y (argumentos) se copian en los parámetros a y b, x = 1, y = 2 } Si ejecuta este programa, puede ver que los valores de las variables x e y no han cambiado. Para que los parámetros cambien los valores de los argumentos, debe utilizar datos que pasan por referencia. Para ello, debe escribir ref antes del nombre del tipo de datos en el encabezado de la subrutina. void Swap (ref int a, ref int b) // ahora las variables a y b obtienen las direcciones de las variables x e y en la memoria { intc; c = un; a = b; b=c; } vacío estático principal () {   entero x=1, y=2;   Intercambiar (ref x, ref y); Aplicación: si pasa un argumento por referencia, entonces solo el nombre de la variable (NO un número y NO una expresión aritmética) puede estar en este lugar al llamar al procedimiento.

No se puede llamar a un procedimiento como este: Intercambiar (x, 4); Intercambiar (5+x, y);