La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Descomponer un problema

Presentaciones similares


Presentación del tema: "Descomponer un problema"— Transcripción de la presentación:

0

1 Descomponer un problema
Problema: Dibujar esta figura Dibujar el círculo Dibujar el triángulo Dibujar las dos líneas secantes Dibujar la línea horizontal Dibujar las otras dos líneas secantes Dibujar figura Dibujar círculo Dibujar triángulo Dibujar líneas secantes * En realidad son el mismo “subproblema” Dibujar líneas secantes Dibujar línea horizontal

2 Descomponer un problema de programación
* * * * * Problema: Imprimir este mensaje horizontal en la pantalla (formando cada letra con asteriscos) Imprimir HOLA Imprimir H Imprimir O Imprimir L Imprimir A Imprimir dos líneas en blanco Imprimir YO Imprimir Y H O L A Y

3 Descomponer un problema de programación
Imprimir mensaje Imprimir HOLA Líneas en blanco Imprimir YO Imprimir H Imprimir A Imprimir Y Imprimir O * Mismo subproblema de programación (= mismo código) Imprimir O Imprimir L

4 Los subprogramas Subprogramas: bloques de código que llevan a cabo una tarea concreta (= resuelven un subproblema concreto) Tienen un propósito Tienen unas precondiciones Permiten reutilizar código de manera sencilla y segura Pueden ser usados más de una vez en el programa principal sin necesidad de reescribir todo (o copiar-pegar) Ayudan a que el código del programa principal sea Legible: Resulta más sencillo leer sólo el nombre del subprograma que todo su código Ordenado: Cada subprograma ocupa un lugar concreto dentro de todo el código

5 Ejemplos de subprogramas
Ejemplo: Podemos pensar en subprogramas para… Imprimir una letra con asteriscos en la consola Mostrar un menú de opciones Pedirle datos al usuario Calcular el máximo de 3 números De hecho, ya conocemos (y hemos utilizado) algunos subprogramas que no hemos implementado nosotros Para leer del teclado: readln, read,… Para escribir por pantalla: write, writeln,… Para operar con números: sqr, sqrt, ln, exp, abs… Para limpiar la consola: clrscr

6 Datos en un subprograma
Dos tipos de datos Datos locales Variables y constantes declaradas y usadas dentro del subprograma Datos intercambiados con el exterior (= parámetros) Datos de entrada (aceptados por el subprograma) Datos de salida (devueltos por el subprograma) Datos de entrada/salida (aceptados y devueltos, posiblemente modificados por el subprograma)

7 Datos en un subprograma

8 Ejemplos Ejemplo Subprograma que, dado un número, lo muestra por pantalla Subprograma que, dado un carácter, devuelve su código ASCII Subprograma que, dado un número, lo devuelve multiplicado por sí mismo numero caracter codigo numero x x2

9 Procedimientos en Pascal
Hay que distinguir entre la declaración y la invocación de procedimientos. La declaración sirve para definir el procedimiento La invocación se utiliza para usar el procedimiento dentro del programa principal (o de otro procedimiento).

10 Ejemplo de un procedimiento en Pascal
Ejemplo: Subprograma que, dado un número, calcula y devuelve el número correspondiente a su cuadrado Declaración Invocación {Calcula el cuadrado de un número} procedure calcCuadrado (num: integer; var cuadrado: integer); begin cuadrado:= num * num; end; var numero, resultado: integer; begin readln(numero); calcCuadrado(numero, resultado); writeln(‘El cuadrado es ’, resultado); end.

11 Ejemplo de un programa con procedimientos
program figuras ; procedure DibujaCirculo ; begin {DibujaCirculo} Writeln (‘ * ’); Writeln (‘* *’); Writeln (‘ * *’); end; {DibujaCirculo} procedure Dibujalineas ; begin {Dibujalineas} Writeln (‘ /\ ’); Writeln (‘ / \ ’); Writeln (‘/ \’); end; {Dibujalíneas} procedure Dibujabase ; begin {Dibujabase} Writeln (‘ ‘); end; {Dibujabase} begin {Programa principal} DibujaCirculo; Dibujalineas; Dibujabase; end.

12 Declaración de procedimientos en Pascal

13 Declaración de procedimientos en Pascal
Para controlar el intercambio de información de un subprograma con el exterior se usan los parámetros Tipos de parámetros Parámetros por valor  Datos solo de entrada Parámetros por referencia (o por variable)  Datos de salida o de entrada/salida Normalmente serán modificados dentro del procedimiento

14 Declaración de procedimientos en Pascal
Ejemplos : procedure escribeH; procedure prueba1 (var num: integer); procedure prueba2 (num1: integer; var num2: integer); procedure prueba3 (p2, p3: real; p5, p6: boolean; var p1: char; var p4: integer); Aunque el orden no es relevante, mejor acostumbrarse a poner los parámetros de entrada/salida siempre al principio o al final de la lista

15 Invocación de procedimientos
Llamada (o invocación) a procedimientos Para aquellos parámetros del procedimiento que son por variable, el argumento sólo puede ser una variable

16 Invocación de procedimientos
En la invocación de un procedimiento debe existir una correspondencia entre los argumentos usados en al invocación y los parámetros definidos en la declaración La invocación debe tener tantos argumentos como parámetros tiene la declaración ¡Y en el mismo orden! A un parámetro por valor le puede corresponder un argumento en forma de constante, variable o expresión Debe haber compatibilidad en la asignación A un parámetro por variable le puede corresponder únicamente un argumento en forma de variable del mismo tipo La llamada a un procedimiento es una sentencia NOTA: Observar la diferencia en este punto con las funciones que veremos más adelante

17 Invocación de procedimientos
Ejemplos var ch1: char;numReal: real; numEntero: integer; incognita: boolean; escribeH; prueba1 (num); prueba1 (numEntero); prueba2 (5, numEntero); prueba3 (ch1, numReal, numEntero, incognita, false); prueba3 (‘a’, numReal, 3 * numReal, numEntero, incognita, false); prueba3 (ch1, numReal, 3 * numReal, numEntero, incognita, true); Explicación en PIZARRA ¿Qué llamadas son correctas?

18 Parámetros: ejemplo program paso; var X,Y : Real ; sum, med : Real;
procedure SumayMedia (num1, num2 :Real; Var Suma, media : Real); begin { SumayMedia } suma := num1 + num2 ; media := suma / 2.0 end; { SumayMedia } begin X :=8 ; Y :=10 ; ... SumayMedia(X,Y,sum,med); writeln(sum); writeln(med); end.

19 El programa usa correctamente los parámetros de entrada y salida
Traza Prog. principal Procedimiento sumaYMedia(X,Y,sum,med) 8.0 X Y sum med 8.0 num1 num2 10.0 10.0 antes antes antes ? suma media ? 8.0 X Y sum med 8.0 num1 num2 10.0 10.0 18.0 después después después suma media 9.0 El programa usa correctamente los parámetros de entrada y salida

20 ¡Aunque el valor de la X cambia, la A no se ve afectada!
Parámetros por valor program paso; var A : integer; procedure incrementa (X:integer); begin X:=X+1; end; A:=5; incrementa(A); writeln(A); end. Prog. principal Procedimiento A A X 5 5 antes Por valor A X 5 6 después ¡Aunque el valor de la X cambia, la A no se ve afectada! Luego en este caso el procedimiento incrementa es en realidad inutil porque no tiene ningún efecto

21 Parámetros por referencia o variable
program paso; var A : integer; procedure incrementa (var X:integer); begin X:=X+1; end; A:=5; incrementa(A); writeln(A); end. En la invocación incrementa(A) se asocia la variable A del programa principal con el parámetro X de la declaración del procedimiento incrementa Prog. principal Procedimiento A X 5 antes Por variable A X 6 después Como el paso de parámetros es por variable, al incrementarse la X se está incrementando en realidad la A declarada en el programa principal.

22 No se debe acceder a variables globales (I)
{Mostrar un número varias veces} program muestraRepetida; var num, veces: integer; procedure mostrar; cont: integer; begin for cont:= 1 to veces do writeln(num) end; begin write(‘Introduzca el número: ‘); readln(num); write(‘Introduzca las veces: ‘); readln(veces); mostrar end. Este programa funciona, pero… El procedure mostrar está accediendo a las variables veces y num que están definidas en el programa principal A eso se le llama acceder a una variable global

23 No se debe acceder a variables globales (II)
{Mostrar un número varias veces} program muestraRepetida; var num, veces: integer; procedure mostrar; cont: integer; begin for cont:= 1 to veces do writeln(num) end; begin write(‘Introduzca el número: ‘); readln(num); write(‘Introduzca las veces: ‘); readln(veces); mostrar end. Uso de VARIABLE GLOBAL!!! Uso de VARIABLE GLOBAL!!! Un procedimiento sólo debe acceder a sus parámetros y a las variables que tiene definidas localmente en su zona de declaraciones. La idea es que el procedimiento encapsule los datos que necesita utilizar y, por tanto, NO debe acceder a variables de otros procedimientos o del programa principal

24 No se debe acceder a variables globales (y III)
{Mostrar un número varias veces} program muestraRepetida; var num, veces: integer; procedure mostrar (n, v: integer); cont: integer; begin for cont:= 1 to v do writeln(n) end; begin write(‘Introduzca el número: ‘); readln(num); write(‘Introduzca las veces: ‘); readln(veces); mostrar(num, veces) end. En este caso, mostrar solo utiliza sus parámetros n y v y a su variable local cont, lo cual es correcto

25 Explicación en PIZARRA
Ejercicios Subprograma que intercambia dos valores reales dados Subprograma que, dado un número entero positivo N, calcula y devuelve la suma y la media de los N primeros enteros positivos Subprograma que calcula el factorial de un número entero N Explicación en PIZARRA

26 Funciones Son un tipo especial de subprogramas que se pueden emplear dentro de expresiones La declaración se realiza en el mismo sitio que las de los procedimientos Su invocación puede realizarse en cualquier punto donde se pueda utilizar un literal Es decir, pueden emplearse dentro de expresiones o en la parte derecha de una asignación Cada llamada a una función se comporta como su valor resultante Y no como una sentencia normal de Pascal (como pasaba con los procedimientos)

27 ¿Cuándo usar funciones?
Si se necesita un subprograma que calcule y devuelva un único valor Se pueden usar de manera similar a un literal Dentro de expresiones (siendo el valor devuelto por la expresión compatible) En la parte derecha de una sentencia de asignación Como argumento de procedimientos u otras funciones Es recomendable que el subprograma no tenga interacción con el usuario mediante sentencias de entrada o de salida Algunas cosas a tener en cuenta Sólo utilizarán parámetros de entrada (de paso por valor) Un solo parámetro de salida de tipo simple o string NO se define en la lista de parámetros Tiene como nombre el mismo nombre de la función 4.27

28 Sintaxis de las funciones en Pascal
Tipo de la función

29 Sintaxis de las funciones en Pascal
Llamada (o invocación) a funciones Tantos argumentos como parámetros Cada uno de los argumentos se corresponde con el parámetro situado en la misma posición que él

30 Ejemplo de una función en Pascal
Ejemplo: función que, dado un carácter, devuelve un valor booleano indicando si se trata de un dígito o no function esDigito (ch: char): boolean; begin esDigito:= (ch >= ‘0’) and (ch <= ‘9’) end; Código para devolución del valor de la función: identificadorFuncion:= valor

31 Ejemplo {Comprobar si un carácter es un dígito o no} program prueba;
var mi_char: char; function esDigito (ch: char): boolean; begin esDigito:= (ch >= ‘0’) and (ch <= ‘9’) end; begin (* p.p. *) writeln(‘Introduzca un carácter: ‘); readln(mi_char); if esDigito(mi_char) then writeln(‘Es un dígito’) else writeln(‘No es un dígito’) end. (* p.p. *) En este punto se ejecuta la función esDigito y se le pasa el valor de mi_char. Al final, esDigito(mi_char) será un valor booleano, que es compatible con lo que espera la instrucción IF en ese punto

32 Otro ejemplo {Mostrar los días del mes} program diasDelMes; var
mes: integer; function diasMes (m: integer): integer; begin case m of 1,3,5,7,8,10,12: diasMes:= 31; 4,6,9,11: diasMes:= 30; 2: diasMes:= 28 end end; begin (* p.p. *) write(‘Introduzca el mes: ’); readln(mes); if (mes >= 1) and (mes <= 12) then writeln(‘Días: ’, diasMes(mes)) end. (* p.p. *)

33 Usando bien la variable de salida
function producto (X, Y : integer) : integer; {Calcula X * Y mediante sumas} var I, prod : integer ; begin prod:=0; for I:=1 to X do prod : = prod + Y; {sumamos Y X veces} producto := prod; end; Si se van a realizar cálculos intermedios, es recomendable trabajar primero sobre una variable local Al final se realiza la asignación de la variable local a la variable de salida (que tiene como identificador del nombre de la función)

34 Procedimientos anidados
Dentro de los subprogramas se pueden definir otros subprogramas En Pascal, un procedimiento puede llamar a cualquier otro procedimiento que esté declarado previamente Pero no puede llamar a procedimientos declarados posteriormente (es decir, más abajo en el código) Imprimir mensaje Imprimir HOLA Líneas en blanco Imprimir YO Imprimir O Imprimir Y Imprimir H Imprimir L Imprimir A

35 Visibilidad de Procedimientos
program miPrograma; var x, y: real; procedure externo (var x: real); m, n: integer; procedure interno (x: real); n, p: integer; begin (* interno *) ... end; (* interno *) begin (* externo *) end; (* externo *) procedure otro; const blanco = ‘ ‘; begin (* otro *) ... end; (* otro *) begin (* p.p. *) end. (* p.p. *)

36 Alcance y visibilidad de variables y constantes
Tipos de identificadores Locales a bloque Declarados en el bloque No locales a bloque  Declarados en un nivel de anidamiento superior al del bloque Regla de alcance El alcance de un identificador son las sentencias posteriores del bloque en el que se declara y las de los bloques anidados posteriores a su declaración Regla de visibilidad Si dos identificadores con igual nombre tienen alcance en una determinada zona del programa, en dicha zona sólo es visible el de menor alcance La visibilidad de un identificador incluye todas las sentencias posteriores del bloque en el que se declara y las de los bloques anidados posteriores a su declaración en los que el identificador no se redeclara

37 Explicación en PIZARRA
Ejercicio program miPrograma; var x, y: real; procedure externo (var x: real); m, n: integer; procedure interno (x: real); n, p: integer; begin (* interno *) ... end; (* interno *) begin (* externo *) end; (* externo *) begin (* p.p. *) end. (* p.p. *) Explicación en PIZARRA m? n? p? x? y?

38 Estilo de programación
Los subprogramas deben documentarse igual que debe hacerse con el resto del programa: Documentación de programas Objetivo Entrada/salida (interacción con el usuario) Puede incluir también otra información relevante, tal como algoritmos que implementa, fecha de creación, fecha de la última modificación, nombre del/de los programador(es), etc. Documentación de subprogramas Datos aceptados, devueltos y aceptado y devueltos posiblemente modificados

39 Estilo de programación
function diasMes (m: integer): integer; { Objetivo: Obtiene el número de días de un mes Acepta: El número entero que representa al mes (m); m  [1,12] Devuelve: El número de días del mes } begin ... end; procedure mostrar (n, v: integer); Objetivo: Visualiza un número entero un cierto número de veces Acepta: El número entero a mostrar (n) y el número de veces que se muestra (v) Salida (pantalla): Tantas líneas como veces se quiere mostrar el número; cada línea contiene el número var

40 Diseño descendente Tratamiento de los problemas mediante refinamientos sucesivos (descomposición del problema en subproblemas cada vez más pequeños) Ejemplo: Diseñar y escribir un programa que haga operaciones de conversión de cantidades hasta que el usuario decida que no quiere hacer más transformaciones Centímetros a pulgadas (e inversa) Kilogramos a libras (e inversa) Euros a pesetas (e inversa) Grados centígrados a grados Fahrenheit (e inversa)

41 Primer diseño Programa principal Repetir Elegir opción
Ejecutar opción elegida Mostrar resultado Hasta que la opción elegida se distinta de cero

42 Primer refinamiento Subprograma elegir_opcion
Repetir Mostrar menú con las opciones Leer la opción elegida Hasta que la opción sea válida Subprograma ejecutar_opcion Si el valor de la opcion es: 1  traducir_cms_pulgadas 2  traducir_kgs_libras 3  traducir_euros_pts 4  traducir_cent_fahr 0  No hacer nada Programa principal Elegir opción Ejecutar opción elegida Mostrar resultado Hasta que la opción elegida se distinta de cero

43 Subprograma mostrar_menu
Segundo refinamiento Subprograma mostrar_menu Escribir la estructura del menú con writeln Subprograma elegir_opcion Repetir Mostrar menú con las opciones Leer la opción elegida con readln Hasta que la opción sea válida

44 Segundo refinamiento (cont)
Subprograma traducir_cms_pulgadas Pedir tipo de conversión (cms->pulgadas, pulgadas->cms) Pedir la cantidad original Si cms->pulgadas Calcular_pulgadas Si no Calcular_cms Subprograma ejecutar_opcion Si el valor de la opcion es: 1  traducir_cms_pulgadas 2  traducir_kgs_libras 3  traducir_euros_pts 4  traducir_cent_fahr 0  No hacer nada

45 Subprograma pedir_tipo_conversion_cms_pulgadas
Tercer refinamiento Subprograma pedir_tipo_conversion_cms_pulgadas Función calcular_pulgadas(cent: real) : real; Función calcular_cms(pulgadas: real) : real; Subprograma traducir_cms_pulgadas Pedir tipo de conversión (cms->pulgadas, pulgadas->cms) Pedir la cantidad original con readln Si cms->pulgadas Calcular_pulgadas Si no Calcular_cms


Descargar ppt "Descomponer un problema"

Presentaciones similares


Anuncios Google