Fundamentos de la Programación

Anuncio
TEMA 7. METODOLOGÍA DE LA PROGRAMACIÓN
Una aplicación informática se compone de programas que tienen por objeto la realización automática de una o
varias tareas mediante el uso de un sistema informático. El proceso desde el planteamiento del problema hasta
que se tiene la solución informática instalada en una o varias computadoras, se denomina ciclo de vida de una
aplicación informática. Este se descompone en varias fases:
FASES de DISEÑO FASES de INSTALACIÓN
Problema
Ingenieros
Especificación Programa fuente
Diplomados/IT
Algoritmo Programa objeto
Técnicos FP
Ejecutable
Aplicación
• Análisis. Consiste en el examen y descripción detallada de los siguientes aspectos relativos al
problema: equipo a utilizar, personal informático necesario, estudio de los datos de entrada, estudio de
los resultados que se pretenden obtener, relación entre la entrada y la salida, y descomposición del
problema en módulos.
Resultado: documentos que componen la especificación del problema.
• Programación. Consiste en el diseño de la solución al problema planteado en forma de algoritmo.
Resultado: documentos integrados por herramientas de representación de algoritmos como
seudocódigo, ordinogramas, etc...
• Codificación. Transcripción del algoritmo resultante de la fase anterior a un lenguaje de codificación
concreto. Resultado: se denomina programa y antiguamente solía devolverse o generarse un
documento en papel denominado hoja de codificación o cuaderno de carga.
• Edición. Se escribe el programa fuente a partir de las hojas de codificación en la memoria del
ordenador, y se graba en algún soporte permanente.
• Compilación. Traducción del programa fuente aún programa objeto o compilado, con programas
traductores.
• Fase de montaje o linkado. Se añade al programa objeto una serie de rutinas del sistema. Resultado:
programa ejecutable directamente en la máquina sin necesidad de traductor.
• Prueba de ejecución. Consiste en ejecutar el programa con una serie de conjuntos de datos de prueba
para comprobar si el funcionamiento de éste entra dentro de los estándares de calidad fijados.
• Explotación y mantenimiento. La explotación consiste en el uso continuo y habitual por parte de los
usuarios de la aplicación en un entorno. El mantenimiento de la aplicación consiste en la
comprobación del buen funcionamiento de ésta y en la adaptación a cualquier nueva circunstancia que
1
implique su actualización.
Según el momento en el que se detectan los errores, podemos clasificarlos en los siguientes tipos:
• Errores de compilación. Corresponden al incumplimiento de las reglas sintácticas del lenguaje. Por
ejemplo palabras clave mal escritas, falta de delimitadores. Son los mas fáciles de corregir.
• Errores de ejecución. Se deben a operaciones no permitidas, como dividir por cero, leer un dato
numérico en una variable numérica, etc...Se detectan porque se produce una parada anormal del
programa.
• Errores de lógica. Corresponden a la obtención por el programa de resultados que no son correctos.
Son bastantes difíciles de encontrar, sólo se puede ser ejecutando un número suficiente de juegos de
prueba y compararlos con los datos producidos por el programa con los que generaríamos a mano, o
bien con una aplicación suficientemente probada.
• Errores de especificación. Se deben a la realización de unas especificaciones incorrectas, debidas a
la mala comunicación entre el equipo de desarrollo y quien platea el problema.
La elección del algoritmo más adecuado se debe basar en una serie de requerimientos de calidad que
adquieren gran importancia a la hora de evaluar costes de diseño y mantenimiento, que son los siguientes:
• Legibilidad. Claro y sencillo, que resulte fácil su lectura y su compresión.
• Fiabilidad. Robusto, es decir, capaz de recuperarse ante errores y usos inadecuados.
• Portabilidad. A dos niveles: 1) los algoritmos generados en la fase de programación deben ser
implementables en diferentes lenguajes; 2) los códigos fuente obtenidos deben ser independientes de
la máquina y del SO.
• Modificabilidad. El código ha de ser fácil de mantener, o sea, ha de permitir que se realicen cambios
para adaptarlos a nuevas situaciones.
• Eficiencia. El programa generado tendrá que hacer un uso correcto y ajustado de los recursos que no
son ilimitados.
La metodología de la programación es un conjunto de métodos y técnicas disciplinadas que ayudan al
desarrollo de unos programas que cumplan los requisitos anteriormente expuestos. Estos objetivos suelen ser
la programación modular que consistía en una serie de descomposiciones del problema hasta llegar a un
conjunto de módulos implementables.
La programación estructurada consiste en el uso exclusivo de las estructuras secuencia, selección e iteración
para el control de flujo de las instrucciones.
La Documentación de los Programas está constituida principalmente por una serie de anotaciones dentro del
propio código fuente y por una serie de documentos que acompañan a la aplicación software. Su fin es
facilitar la explotación y el mantenimiento de la aplicación, y debe ser amplia, clara y precisa. Existen dos
tipos de documentos:
• Interna. Está constituida básicamente por el listado del programa fuente y su objetivo es facilitar la
lectura y comprensión del mismo. Se considera parte de la documentación interna los siguientes
aspectos:
• Comentarios. Son frases explicativas que se colocan en cualquier parte del programa fuente, ignoradas por
el compilador. Es conveniente incluir comentarios con aquellos razonamientos que nos hayan sido difíciles
de alcanzar y que preveamos que van a ser difíciles de comprender pasado un tiempo.
• Código autodocumentado. Las palabras reservadas de los lenguajes de alto nivel se podrían considerar
como parte de la documentación por corresponder con términos en inglés que expresan su contenido.
2
• Externa. Es el conjunto de documentos que se acompaña con el programa, pero sin formar parte de
los ficheros fuente. La documentación externa debe influir a los siguientes apartados: especificación
del análisis, descripción del diseño del programa, de las versiones si las hubiera, del programa
principal y los subprogramas, de los manuales del usuario y el anual del mantenimiento.
Las técnicas de desarrollo y diseño de programas usadas en la programación convencional tienen
inconvenientes sobre todo a la hora de verificar y modificar un programa. Una técnica que se está
implantando, para paliar los problemas exteriores al ciclo de vida de la aplicación, es la descomposición de un
problema en problemas cada vez más pequeños hasta llegar a módulos implementables, Top−down, en el cual
tenemos la programación estructurada.
Las técnicas de programación estructurada pretenden resolver los saltos condicionales y los incondicionales,
las cuales se pueden definir como la programación sin saltos condicionales e incondicionales. Las
características de un programa estructurado son las siguientes: fácil de leer y comprender, fácil de codificar en
una amplia variedad de lenguajes y sistemas, fácil de mantener, eficiente (aprovechando al máximo los
recursos del sistema) y modularizable.
Un diagrama propio es aquel que sólo posee una entrada y una salida.
Un programa propio es el que solo tiene un punto de entrada y otro de salida, y donde todo elemento del
programa es accesible, es decir, existe al menos un camino de los que van del inicio al fin que pasa por él; es
un programa que no tiene bucles infinitos.
Dos programas son equivalentes si ante cualquier situación de datos proporcionan el mismo resultado pero de
distinta forma.
Todo programa propio tiene siempre al menos un programa propio equivalente que sólo utiliza las estructuras
básicas de programación, que son la secuencia, selección e iteración. O sea, que diseñando programas con
sentencias primitivas y estructuras básicas podremos hacer cualquier trabajo y considerar en mejorar la
creación, lectura, comprensión y mantenimiento de los programas.
La programación estructurada utiliza:
• Diseño Top Down. Los programas se diseñan de lo más genérico a lo más particular por medio de
sucesivos refinamientos o descomposiciones que nos llevarán a las instrucciones particulares de cada
programa.
• Recursos abstractos. Es el complemento perfecto para el diseño Top−Down y, en el cual, utilizamos
el concepto de abstracción, es decir, en cada descomposición suponemos que las partes resultantes
están resueltas, dejando su realización al siguiente refinamiento y considerando que al final estarán
formadas por un conjunto de instrucciones y estructuras básicas.
• Estructuras básicas. Toda acción se puede realizar usando las 3 estructuras básicas de control, es
decir, la secuencial, alternativa y la repetitiva.
• Estructura secuencial. Es una estructura con una entrada y una salida, cuya ejecución es lineal y las
acciones se ejecutarán en el orden en el que aparecen. Cada acción sólo tendrá una entrada y una salida.
• Estructuras alternativas. Es una estructura con una sola entrada y una sola salida, de la cual se realiza una
opción según una condición. Ésta puede ser simple o compuesta. Las alternativas pueden ser de dos tipos:
1ª, dos salidas condicionales, una de las cuales puede ser nula; y 2ª, tres o más salidas.
• Estructura repetitiva. Estructura con una entrada y una salida, en la cual se repite un número determinado o
indeterminado de veces, dependiendo de una determinada condición.
3
FOR: se repite una acción un determinado número de veces representado normalmente por N.
no
si
WHILE: Se repite una acción mientras que se cumpla la condición que calcula el bucle. La condición es
evaluada siempre antes de cada repetición.
no
si
DO/WHILE: Se repite una acción mientras se cumpla la condición que controla el bucle. La condición se
evaluará después de cada repetición del bucle.
si
Un árbol o estructura arborescente es un grafo en el que se distinguen generalmente tres clases de nodos: raíz,
nodos intermedios y hojas.
La raíz es el nodo del que parte toda la estructura del árbol, es decir, es un nodo que sólo tiene salidas.
Los nodos intermedios son los que tienen una entrada o enlace de entrada o al menos una salida o enlace de
salida.
Las hojas son nodos que se sitúan en la parte más lejana a la raíz y que sólo tienen entradas.
Existen tres tipos de ordenar un árbol:
• Preorden. Consiste en los siguientes tres pasos: 1º, consultar la raíz; 2º, consultar el subárbol; y 3º,
consultar el subárbol derecho.
• Inorden. 1º, Recorrer el subárbol izquierdo hasta llegar a una hoja y tratar esa hoja. 2º Consultar la raíz. 3º,
recorrer el subárbol derecho hasta llegar a una hoja y tratarla.
• Postorden. 1º, recorrer el subárbol izquierdo hasta llegar a una hoja. 2º, recorrer el subárbol derecho hasta
llegar a una hoja. 3º, consultar la raíz.
El método de Jackson es un método de representación de programas en forma de árbol y que se denomina
diagrama arborescente de Jackson. Consta de las siguientes partes:
• Definición detallada de los datos de E/S, incluyendo los archivos lógicos utilizados.
• Representación del proceso o algoritmo. La simbología utilizada en este método se puede describir como el
uso de rectángulos que tienen los siguientes aspectos:
Acción Decisión Repetición
La lectura del diagrama generado se hace en preorden y la representación de un algoritmo se basa en los
siguientes tres puntos:
• Un programa se representa por un solo diagrama en el que se incluyen todas las operaciones necesarias para
solucionar el problema. La forma para conectar dos páginas es mediante la palabra `proceso' encerrada en
un rectángulo y con un número o nombre.
4
• Todo diagrama comienza con un rectángulo en cuyo interior figura el nombre del programa.
• Se ha de procurar, para facilitar la lectura, que el diagrama que generemos sea lo más simétrico posible.
FOR: en el rectángulo de condición se escribirá o bien en número de veces que se va a repetir el bucle o bien
el nombre de la variable contador, su valor inicial, su valor final y el incremento. Ej.: queremos que la
condición se repita 5 veces.
MIENTRAS/WHILE: en el rectángulo de Condición se escribirá la condición que rige el bucle.
HASTA: En el rectángulo de Condición se pondrá `hasta' y la condición. Por ej.:
El método de Chapin se trata de una forma de representar programas como un bloque compacto que consta de
dos cosas:
• Definición detallada de los datos de E/S, incluyendo los archivos lógicos utilizados.
• Representación del proceso o algoritmo.
Su simbología se basa en el empleo de rectángulos y la lectura del gráfico generado se hace de arriba a abajo.
La representación del algoritmo se basa en los siguientes puntos:
• Un programa se representa por un solo diagrama en el que se incluyen todas las operaciones a realizar para
la resolución del problema.
• Todo diagrama comienza en un rectángulo en el que su parte superior y fuera de él figura el nombre del
programa.
• Estructura secuencial. Son como un conjunto de acciones secuenciales, donde ABCD se ejecutarán
de arriba a abajo.
• Estructura alternativa. Puede ser: simple o de una opción, doble o múltiple.
• Estructura iterativa.
FUNDAMENTO DE PROGRAMACIÓN (3)
El diseño descendente o toc−down consiste en una serie de descomposiciones sucesivas del problema inicial
que reciben un refinamiento progresivo del repertorio de instrucciones que van a formar parte del programa.
Sus objetivos son:
• Simplificación del problema y de los subprogramas resultantes de cada descomposición.
• Programación independiente de cada uno de los módulos, incluso por diferentes personas.
• Simplificación de la lectura y el mantenimiento del programa final.
Un programa diseñado en Toc−Down tiene dos partes bien diferenciadas:
• Programa principal. Describe la solución completa del programa y consta principalmente de llamadas a
subprogramas. Estas llamadas son indicaciones al procesador de que debe continuar la ejecución del
programa en el comienzo del subprograma llamado, regresando al punto de partida una vez que lo haya
concluido. Además, puede contener operaciones e instrucciones primitivas del lenguaje, y sentencias de
control ejecutables por el procesador. Debe ser breve.
• Subprogramas. Figuran agrupados en un lugar distinto al programa. Su estructura es parecida a la del
programa principal, salvo en el encabezamiento y la finalización. Éste puede tomar sus propios
subprogramas correspondientes. La función de un subprograma es la de resolver una parte del problema.
5
Éstos se dividen en:
• Subprogramas internos. Son aquellos subprogramas que están localizados en el mismo archivo que el
programa principal.
• Subprogramas externos. Son aquellos que figuran físicamente separados del programa principal, es decir,
en distintos ficheros fuente. Se pueden compilar independientemente y también los podemos encontrar en
un lenguaje diferente del programa principal.
Los objetos manipulados por un programa se clasifican según su porción de programa y/o subprogramas en
que son definidos y conocidos.
Los objetos globales son los declarados en el programa principal, cuyo ámbito se extiende al mismo y a todos
sus subprogramas. Se pueden ver desde cualquier parte del programa.
Los objetos locales de un subprograma son los declarados en dicho subprograma, cuyo ámbito está restringido
a él mismo y a los subprogramas declarados en él. Sólo se puede ver dentro de él.
Cada vez que se llama a un subprograma, los datos de entrada le son pasados por medio de determinadas
variables, y análogamente, cuando termina la ejecución los resultados regresan mediante otras o las mismas
unidades.
Los parámetros pueden ser:
• Parámetros formales. Son variables locales de un subprograma utilizadas para la recepción y el envío de
los datos. Siempre son fijos.
• Parámetros actuales. Son las variables y datos enviados en cada llamada de subprograma por el programa
o subprograma llamante. Son los valores y cambian.
Se denomina paso de parámetros al proceso de transmisión y recepción de datos y resultados mediante
variables de enlace. Puede realizarse de dos modos:
• Paso por valor o copia. Cuando pasamos una variable a un subprograma, realmente le pasamos una copia
de su valor, conservándose el valor de la variable aunque se modifique dentro del subprograma a la salida
de éste.
• Paso por referencia o variable. Cuando le enviamos una variable, le pasamos la dirección de ésta. En este
caso, el cambio que se produzca en el programa aparecerá reflejado al acabar la ejecución de éste.
Un parámetro actual pasado por valor es un dato de entrada al subprograma, y se copia en su parámetro
formal correspondiente. No se proporciona la variable al subprograma, sino sólo su contenido.
Un parámetro actual pasado por referencia es una variable del programa llamante, para el programa llamado,
el cual coloca un resultado en esa variable, que queda a disposición del llamante una vez ha concluido la
ejecución del programa. Proporciona su dirección de memoria al parámetro formal asociado, pudiendo
modificarla, y dejando en ellas los valores que va a devolver. Estos parámetros suponen un ahorro de
memoria, puesto que la variable local no existe realmente, sino que se asocia a la global en cada llamada.
Una función es un subprograma que recibirá una serie de parámetros en la posición y de los tipos indicados en
su lista de parámetros y que va a devolver un único valor de un tipo determinado que será el tipo de la
función.
Los procedimientos son un tipo de subprogramas que recibirán una serie de parámetros o argumentos en la
cantidad, tipo y posición que indique su lista de parámetros realizará un determinado proceso y no devolverá
ningún resultado de modo explícito. Es para cuando queremos modificar o devolver más de un valor o
6
variable u operar con una estructura de datos compleja.
Las funciones en C son el bloque principal en la construcción de programas. La forma general es:
Especificador_de_tipo nombre_de_función (lista_de_parámetros)
{
<secuencia de acciones>
}
El especificador_de_tipo es el tipo de dato que devolverá la función mediante la sentencia `return'. Si no lo
especificamos, el compilador asume un tipo de vuelta concreto.
La lista_de_parámetros es la lista de nombre de variables separadas por comas y con sus tipos asociados que
reciben los valores de loa parámetros o argumentos cuando se llama a una función. Puede no tener ningún
parámetro, y entonces pondremos `void'.
Return tiene dos usos importantes:
• Forzar una salida inmediata de la función en la que nos encontramos.
• Devolver un valor, generalmente, calculado en la función.
Hay dos formas de cómo una función puede terminar su ejecución y que ésta devuelva al sitio desde el que se
la llamó:
• Modo implícito. Se produce al llegar a la llave que cierra el código de la función.
• Modo explícito. Porque tienen que devolver un valor o para simplificar el código de la función y hacerlo
más eficiente permitiendo varios puntos de salida.
Todas las funciones, excepto void, devuelven un valor. Si la función no es especificada como `void' y no se
especifica un valor de vuelta, entonces el valor devuelto por la función queda técnicamente indefinido. Hay
varios tipos de funciones:
• Funciones computacionales. Diseñadas para operar con sus argumentos y devolver un valor basado en
esos cálculos.
• Son aquellas funciones que manipulan la información y nos devuelven un valor que indica únicamente el
éxito o fracaso de tal manipulación. Como eje: la función de librería fwrite() que sirve para escribir en un
fichero.
• Son funciones que no tienen un valor de vuelta explícito y son estrictamente de tipo procedimiento sin
generar un valor. Por ejemplo, la función srand() que inicializa la semilla del generador de números
aleatorios.
Algunas funciones devuelven algo de todas formas, aunque no sea de interés, como por ejemplo printf que
devuelve el nº de caracteres escritos.
Cuando se utiliza una sentencia RETURN en main, el programa devuelve un código de terminación al proceso
que lo llamó, y debe ser un entero. En sistemas operativos como MS−DOS o OS/2, un valor de vuelta 0 indica
que el programa ha terminado normalmente. Todos los demás indica que se ha producido algún error.
Las reglas de ámbito de la función son reglas que controlan si un fragmento de código conoce o tiene acceso a
7
otro fragmento de código o datos. Cada función es un bloque de código y es privado a esa función sin poder
accederse a él a menos que se llame a esa función.
El código que comprende el cuerpo de la función está oculto al resto del programa y no se puede acceder ni
modificar.
Se denominan variables locales a las variables definidas de cada función. Existen a partir de que entra en la
función y se destruye cuando sale de ella, es decir, que no conservan su valor entre dos llamadas consecutivas,
a excepción de cuando una variable local se declara con el modificador `static'. Cuando es así, el compilador
la trata como sí fuera global, salvo que sólo sigue siendo visible en el ámbito de la función en la que se
declaró. No se puede definir una función dentro de otra función.
Para usar argumentos se deben declarar variables que acepten los valores de los argumentos. También se
denominan parámetros, los cuales se comportan como variables locales de la función, creándose al entrar en
ésta y destruyéndose al salir de ella.
Se utiliza la llamada por valor para pasar argumentos. Una función por valor se la pasa copia del valor de la
variable.
Es posible causar una llamada por referencia pasando un puntero al argumento.
El paso de arrays o matrices como argumentos es una excepción al convenio de paso por valor que se tiene en
C. Cuando se usa un array como argumento de una función sólo se pasa la dirección de la matriz, no una copia
de los datos de la matriz entera.
C soporta tres argumentos, pero sólo dos son definidos por ANSII: argc y argv. Permiten pasar información al
programa de C mediante la línea de comandos.
Un argumento de línea de comandos es una información que sigue al nombre del programa en la línea de
comandos del sistema operativo.
El parámetro argc contiene el nº de argumentos de la línea de órdenes, o sea, el nº de parámetros que podemos
poner.
El parámetro argv es un puntero a un array de punteros de caracteres. Cada elemento del array apunta a un
argumento de la línea de órdenes. Todos los argumentos de esta línea son tratados como cadenas de
caracteres.
Un prototipo de función es una copia prácticamente literal de la cabecera de la declaración de ésta que se sitúa
generalmente al principio de los ficheros C y forzosamente antes de la 1ª llamada a esa función. Tiene dos
objetivos fundamentales:
• Identificar el tipo de vuelta de la función para que el compilador pueda realizar una generación de código
correcta.
• Especificar el tipo y nº de argumentos que utiliza la función.
Su forma es: tipo nombre función (lista de argumentos)
Problema principal
Subprograma 1
8
Subprograma 2
Subprograma 3
Módulo 1.1
Módulo 1.1
Módulo 1.1
Módulo 1.1
Módulo 1.1
Módulo 1.1
Módulo 1.1
Obtener las actas
Elaboración de actas
Entrada de alumnos y calificaciones
Impresiones de actas
EDICIÓN
ANÁLISIS
COMPILACIÓN
Entrada de alumnos
Entrada de calificaciones
Cálculo de medias
Ordenación de las
actas
Impresión de actas
PROGRAMACIÓN
MONTAJE/LINKADO
CODIFICACIÓN
PRUEBA de EJECUCIÓN
9
EXPLOTACIÓN Y MANTENIMIENTO
EXPLOTACIÓN
PRUEBAS
DESARROLLO
Gestión de datos de clase
Tratamiento
Salida de datos
Entrada de datos
Cálculos Medias asign
Cálculos Medias globales
Captura
Datos Eval/Asign/alumno
Inicialización
Notas globales
V c !V i
V c> Vf
A
Vc = Vc +I
En este tipo de estructuras repetitivas existen dos normas fundamentales de obligado cumplimiento: el valor I
nunca puede ser 0 y V a no puede modificarse en el ámbito del bucle.
Condición
A
A
Condición
+*\A^BCDE
ABC^\D*E+
10
Descargar