Descomponer un problema



Descargar 31,64 Kb.
Fecha de conversión25.04.2017
Tamaño31,64 Kb.

Descomponer un problema

    • * En realidad son el mismo “subproblema”
  • 4.
  • 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
  • Dibujar líneas secantes
  • Dibujar línea horizontal

Descomponer un problema de programación

  • 4.
  • H
  • O
  • L
  • A
  • Y
  • O
  • * *
  • * *
  • * * *
  • * *
  • * *
  • 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
      • Imprimir O

Descomponer un problema de programación

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

Los subprogramas

  • 4.
  • 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

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

Datos en un subprograma

  • 4.
  • 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)

Datos en un subprograma

  • 4.
  • Programa
  • Subprograma

Ejemplos

  • 4.
  • 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
  • x2
  • caracter
  • codigo
  • numero
  • x

Procedimientos en Pascal

  • 4.
  • 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).

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.

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;
  • Dibujalineas;
  • end.

Declaración de procedimientos en Pascal

Declaración de procedimientos en Pascal

  • 4.
  • 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

Declaración de procedimientos en Pascal

  • 4.
  • 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

Invocación de procedimientos

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

Invocación de procedimientos

  • 4.
  • 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

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);
  • 4.
  • ¿Qué llamadas son correctas?

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.

Traza

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

Parámetros por valor

  • program paso;
  • var
  • A : integer;
  • procedure incrementa (X:integer);
  • begin
  • X:=X+1;
  • end;
  • begin
  • A:=5;
  • incrementa(A);
  • writeln(A);
  • end.
  • A
  • 5
  • 5
  • Procedimiento
  • X
  • Por valor
  • A
  • 5
  • 6
  • X
  • ¡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
  • A
  • Prog. principal
  • antes
  • después

Parámetros por referencia o variable

  • program paso;
  • var
  • A : integer;
  • procedure incrementa (var X:integer);
  • begin
  • X:=X+1;
  • end;
  • begin
  • A:=5;
  • incrementa(A);
  • writeln(A);
  • end.
  • A
  • 5
  • Prog. principal
  • Procedimiento
  • X
  • Por variable
  • A
  • 6
  • X
  • 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.
  • 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
  • después
  • antes

No se debe acceder a variables globales (I)

  • 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
  • {Mostrar un número varias veces}
  • program muestraRepetida;
  • var
  • num, veces: integer;
  • procedure mostrar;
  • var
  • cont: integer;
  • begin
  • for cont:= 1 to veces do
  • writeln(num)
  • end;

No se debe acceder a variables globales (II)

  • {Mostrar un número varias veces}
  • program muestraRepetida;
  • var
  • num, veces: integer;
  • procedure mostrar;
  • var
  • 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

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);
  • var
  • 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

Ejercicios

  • 4.
  • 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

Funciones

  • 4.
  • 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)

Funciones

  • 4.
  • ¿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

Sintaxis de las funciones en Pascal

  • Tipo de la función

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

Ejemplo de una función en Pascal

  • 4.
  • Código para devolución del valor de la función:
  • identificadorFuncion:= valor
  • 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;

Ejemplo

  • 4.
  • {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

Otro ejemplo

  • 4.
  • {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. *)

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;
  • 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)

Procedimientos anidados

  • 4.
  • 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 O
  • Imprimir L
  • Imprimir A

Visibilidad de Procedimientos

  • program miPrograma;
  • var
  • x, y: real;
  • procedure externo (var x: real);
  • var
  • m, n: integer;
  • procedure interno (x: real);
  • var
  • 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. *)

Alcance y visibilidad de variables y constantes

  • 4.
  • 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

Ejercicio

  • program miPrograma;
  • var
  • x, y: real;
  • procedure externo (var x: real);
  • var
  • m, n: integer;
  • procedure interno (x: real);
  • var
  • n, p: integer;
  • begin (* interno *)
  • ...
  • end; (* interno *)
  • begin (* externo *)
  • ...
  • end; (* externo *)
  • begin (* p.p. *)
  • ...
  • end. (* p.p. *)
  • m? n? p? x? y?

Estilo de programación

  • 4.
  • 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
      • Objetivo
      • Entrada/salida (interacción con el usuario)
      • Datos aceptados, devueltos y aceptado y devueltos posiblemente modificados

Estilo de programación

  • 4.
  • 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
  • ...
  • begin
  • ...
  • end;

Diseño descendente

  • 4.
  • 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)

Primer diseño

  • 4.
  • Programa principal

Primer refinamiento

  • 4.
  • 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
    • Repetir
      • Elegir opción
      • Ejecutar opción elegida
      • Mostrar resultado
    • Hasta que la opción elegida se distinta de cero

Segundo refinamiento

  • 4.
  • 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

Segundo refinamiento (cont)

  • 4.
  • 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

Tercer refinamiento

  • 4.
  • 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


La base de datos está protegida por derechos de autor ©absta.info 2016
enviar mensaje

    Página principal