Publicado el 25 de Mayo del 2019
612 visualizaciones desde el 25 de Mayo del 2019
632,9 KB
28 paginas
Creado hace 8a (09/12/2015)
3. La abstracción procedimental
1/59
En diseño descencente...
Hemos visto que en diseño descendente los problemas:
se descomponen en subproblemas más sencillos.
Por ejemplo, para el ejercicio de los árboles de navidad hacíamos:
petición de altura de árbol
escritura de cada nivel del árbol; para cada nivel:
escritura de los blancos previos a los asteriscos
escritura de los asteriscos
salto de línea e incremento del contador
cada subproblema se resuelve con independencia del resto:
abstracción
Para escribir los k blancos previos a los asteriscos nos
abstraemos de la escritura de los asteriscos, o de la recogida
del dato altura del árbol
La solución al problema original resulta de la combinación
de las soluciones a los subproblemas.
2/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM Los programas crecen: abstracción
Esta forma de abstracción puede plasmarse en la
implementación mediante
subprogramas: bloques de código independientes
(pero relacionados)
métodos (o funciones) en C#
Hasta ahora hemos escrito todo nuestro código en un solo
método: Main, pero hemos hemos utilizado otros métodos (ya
definidos):
WriteLine, ReadLine, int.Parse, Math.Sqrt,. . .
Nos hemos abstraído de cómo operan esos métodos y los hemos
utilizado sin mayor problema: alguien los ha programado por
nosotros.
Ahora aprenderemos a implementar nuestros propios métodos.
3/59
Ventajas?
Muchas:
programas en fragmentos independientes más pequeños y
Claridad de código: nos permiten trocear grandes
fáciles programar (divide y vencerás!) organización de
código.
Facilidad de diseño
Mayor facilidad de mantenimiento
Depuración de errores más sencilla
Reutilización de código: los métodos tienen un nombre
asociado para llamarlos (ejecutarlos, invocarlos)... y se
pueden ejecutar tantas veces como queramos (también se
pueden agrupar en librerías y distribuir)
Un buen programador es perezoso: intentará hacer cada
trabajo una sola vez.
Nuevas posibilidades: recursión... qué impide que un
método se invoque a sí mismo? Nada.
4/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM Dar nombre a los bloques de código
La idea esencial de un método es sencilla:
dar nombre a un bloque de código
para después poder ejecutar ese código llamando (o
invocando) a ese nombre
agrupar una secuencia de instrucciones y abstraerlas bajo un
nombre
Otra idea esencial: la parametrización
5/59
Ejemplo
Queremos un método para limpiar la consola (dejarla en blanco,
línea con Console.WriteLine ()
Escribimos un bloque de código para hacer esa tarea
{
sin texto) asumiendo que tiene 25 líneas, escribir 25 saltos de
}
int i ;
for (i=0; i<25; i++)
Console.WriteLine();
...y le damos nombre (limpiaPantalla):
static void limpiaPantalla()
{
int i ;
for (i=0; i<25; i++)
Console.WriteLine();
}
Este código se pone dentro de la clase, al mismo nivel que el
método Main. NO dentro del método Main (no se pueden anidar
métodos).
6/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM Ejemplo (II)
limpiaPantalla ();
Ahora, cada vez que queramos limpiar consola, llamamos:
En cierto modo, hemos construido una nueva instrucción
limpiaPantalla () que podemos utilizar cuando queramos.
Qué ocurre cuando se invoca a un método?
<< instrucción1 >>
<< llamada a método >>
<< instrucción2 >>
Tras ejecutar instrucción1 el flujo de ejecución salta al bloque
de código correspondiente a método
Se ejecutan las instrucciones de ese bloque de código
Al teminar el código del método, el flujo vuelve al punto de
llamada y continúa con «instrucción2»
}
7/59
Parámetros
En el ejemplo anterior el método limpiaPantalla () escribe 25
saltos de línea... pero el número de líneas de la consola puede
variar de uno a otro sistema operativo o tipo de consola.
sería más versátil implementar un método que admitiese un
parámetro indicando el número de saltos de línea a escribir
. . . algo así como saltosLinea (n) donde n es un entero que
indica el número de saltos de línea. Implementamos:
static void saltosLinea(int n) // escribe n saltos de línea
{
int i;
for (i=0; i<n; i++)
Console.WriteLine();
Nota: el parámetro n del método se comporta como una
variable de tipo int dentro del método.
Para escribir 25 saltos de línea, llamamos:
saltosLinea(25);
8/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM
Devolución de valores
Los métodos pueden devolver valores (a quien los llame).
Ejemplo: pedir la altura de un triángulo entre unos valores min
y max dados como parámetro y devolver dicha altura:
static double alturaTri(double min, double max){
double alturaT = min − 1 ; // valor "por defecto" no válido
// para forzar entrada en bucle
while (alturaT < min || alturaT > max) { // mientras no válido
Console.Write ("Altura del triángulo [{0},{1}]: ", min, max);
alturaT = double.Parse (Console.ReadLine ());
} // fin while
return alturaT;
En vez de void ahora double como valor de retorno
El valor se devuelve con return ...
}
9/59
Ahora podemos llamar a este método, con los parámetros
adecuados y recoger su valor de devolución:
double alt
alt = alturaTri (10, 200);
Al ejecutar:
Altura triángulo [10,200]: 5
Altura triángulo [10,200]: 567
Altura triángulo [10,200]: 47
En la variable alt tendremos el valor 47.
10/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM Generalizando: más parámetros
El código para solicitar la altura y la base de triángulo es muy
parecido. Lo que cambia es:
El texto para pedir el dato ("Base del triángulo" o "Altura del
triángulo")
Posiblemente los valores máximos y mínimos admitidos. . . ya
están parametrizados en la versión anterior.
Parametrizamos el texto de solicitud de dato y tenemos:
static double pideDato(string texto, double min, double max){
double dato = min - 1; // valor "por defecto" no válido
// para forzar entrada en bucle
while (dato < min || dato > max) { // mientras no valido
Console.Write ("{0} [{1},{2}]: ", texto, min, max);
dato = double.Parse (Console.ReadLine ());
} // fin while
return dato;
}
11/59
Ejecutamos
double alt = pideDato ("Altura triángulo", 10, 200);
double bas = pideDato ("Base triángulo", 5, 300);
Console.WriteLine ("alt: " + alt + "
base: " + bas);
Altura triángulo [10,200]: 5
Altura triángulo [10,200]: 203
Altura triángulo [10,200]: 45
Base triángulo [5,300]: 0
Base triángulo [5,300]: 8
alt: 45
base: 8
Con el mismo código podemos hacer múltiples peticiones de
datos!! (este método podríamos incluso utilizarlo para otros
programas que hemos hecho).
12/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM Sintaxis
La sintaxis (todavía incompleta) de la declaración o prototipo
de un método es:
static tipoResult nombreMétodo ( tipo1 parám1,. . . , tipon parámn )
static indica que es un método de la clase (no nos
preocupa por ahora)
tipoResult es el tipo de dato que devuelve el método: void
si no devuelve nada; int, double, bool. . . , cualquiera de lo
que conocemos
nombreMétodo es un identificador cualquiera (con las
mismas reglas que vimos de formación de identificadores)
tipo1,. . . ,tipon son los tipos de los parámetros (o
argumentos) del método. . . cualquier de los que conocemos
parám1,. . . ,parámn son los identificadores de los parámetros
que recibe el método.
13/59
Sintaxis (II)
Después del prototipo del método viene un bloque de código
(entre "{" y "}") que llamamos cuerpo del método:
es un bloque de código estándar
puede utilizar los parámetros del método, declarados en el
prototipo
y también las variables locales declaradas en este bloque
No puede utilizar variables de otro bloque: no puede utilizar
las variables declaradas en el método Main u otros.
si el método devuelve un tipo relevante (distinto de void)
No están en su ámbito de visibilidad abstracción
debe contener una instrucción
return expresion ;
con una expresion correcta de tipo tipoResult. Si el tipo es
void puede contener return; pero no es necesario (ni
habitual).
Nota: return provoca la terminación inmediata del método
y la vuelta al punto de llamada al mismo (rompe flujo).
14/59
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM En la llamada...
Si tenemos un prototipo:
static tipoResult nombreMétodo ( tipo1 parám1,. . . , tipon parámn )
podemos llamar al método de la forma:
nombreMétodo (val1,. . . , valn )
donde val1,. . . ,valn tienen que ser valores de tipo tipo1,. . . ,tipon.
El valor resultante de la llamada:
se puede recoger en una variable de tipo tipoResult
mediante una asignación var = nombreMétodo(...
o se puede utilizar como valor dentro de otra expresión
Los parámetros con los que se llama al método tienen que
coincidir en número y tipo con los declarados en el prototipo del
método.
15/59
Parámetros y valores de devolución
Los métodos permiten definir bloques de código
independientes, que pueden pensarse e implementarse de
manera aislada.
Los parámetros y el valor de retorno permiten compartir
información con el exterior (con el método llamante).
los parámetros permiten que el método reciba información
el valor de devolución permite devo
Comentarios de: 3. La abstracción procedimental - Fundamentos de la Programación - Grado en Desarrollo de videojuegos (0)
No hay comentarios