01. Introducción

Última modificación por editor1 el 2019/09/04 23:12

Introducción

Esta asignatura es la continuación de Fundamentos de Programación, y por tanto, se parte de unos conocimientos iniciales de programación. Estos conocimientos serán la base tanto de los ejercicios como los nuevos conceptos que se introducirán, y es importante que los tengáis claros. En este módulo se resumen los conceptos que se han dado en Fundamentos de Programación, y tiene enlaces a estos materiales por si necesitáis revisarlos.

También podéis acceder en cualquier momento a los materiales completos con el siguiente enlace:

Fundamentos de Programación

También disponéis de las Transparencias de Síntesis, un conjunto de pequeños documentos que os permitirán hacer un repaso rápido a todos los conceptos.

Transparencias de síntesis

A continuación se muestra un conjunto de pequeñas presentaciones que resumen ciertos aspectos de la asignatura. Están pensadas para servir de repaso rápido, aunque puede aparecer alguna información adicional. Al lado de cada enlace de descarga hay una breve definición del contenido:

Documentos
TS1: Diferencia entre algoritmos y programas.
TS2: Se muestran los principales elementos de la programación en C, desde cómo se compila un programa hasta las estructuras más típicas.
TS3: Estructura de las variables en memoria.
TS4: Memoria dinámica y punteros.

Resumen de conceptos

Durante la asignatura de Fundamentos de Programación hemos visto los conceptos básicos de programación que permiten definir formalmente un algoritmo para resolver un problema dado e implementarlo en lenguaje C.

Algoritmos y programas

Generalmente todo problema a solucionar por medio de un programa informático se expone en lenguaje no formal, o sea, el lenguaje que utilizamos las personas para comunicarnos. Por ejemplo, un enunciado de un problema podría ser:

"Me gustaría tener organizados mis contactos para poder buscar el teléfono a partir de su nombre."

Cualquier persona es capaz de entender este problema, pero desgraciadamente, los ordenadores sólo entienden instrucciones precisas y sin ambigüedades. Por este motivo, el primer paso que habrá que hacer es definir formalmente este problema.

La descripción formal la hacemos mediante el lenguaje algorítmico (conocido como pseudocódigo), un lenguaje que a pesar de ser muy flexible, permite definir de forma precisa y sin ambigüedades el problema. En este caso, habrá que identificar que necesitaremos un tipo de datos que permita representar objetos compuestos de nombre y teléfono, que un nombre es una cadena de caracteres y un número de teléfono una secuencia de números con un formato determinado.

Seguramente también identificaremos que habrá que poder guardar múltiples objetos de este tipo y por tanto que necesitaremos utilizar una tabla. Que por lo menos tendremos que añadir y buscar elementos en esta tabla (posiblemente también modificar y eliminar), y por tanto, será necesario definir los algoritmos que nos permitan llevar a cabo estas acciones.

En este punto, hay que recordar que un algoritmo no es nada más que una secuencia de instrucciones que se ejecutan una después de la otra para resolver un problema.

Una vez tenemos el pseudocódigo definido con los tipos de datos y los algoritmos, el problema ha quedado totalmente formalizado, pero un ordenador todavía no es capaz de entenderlo. Un ordenador sólo entiende secuencias de 0s y 1s (valores binarios), pero para una persona es muy difícil trabajar a este nivel. La solución es utilizar un lenguaje de programación, que a pesar de ser mucho más rígido que el pseudocódigo, es comprensible para una persona. Existen muchos lenguajes de programación, algunos más cercanos al pseudocódigo (alto nivel) y otros más cercanos al lenguaje de la máquina (bajo nivel). En nuestro caso hemos utilizado el lenguaje C, que se considera un lenguaje de nivel medio.

Una vez descrito el problema con el lenguaje de programación, utilizamos el compilador para traducir de forma automática este código en código máquina que el ordenador puede entender, y por tanto, ejecutar.

Enlaces relacionados

Tipo de datos

El nombre de Informática proviene de la fusión entre Información y Automática, y básicamente es la ciencia o técnica de procesar información automáticamente. En la asignatura hemos visto que los algoritmos suelen partir de una información inicial, ya sea leída por teclado, de un fichero o pasada como parámetro. Nuestros algoritmos toman esta información y la organizan, manipulan o hacen cálculos para obtener nueva información, que suele ser el resultado del algoritmo, el cual puede mostrarla por pantalla, guardarla en un archivo o devolverla para que otro algoritmo la pueda utilizar. Por tanto, la pieza clave en todo el proceso es la información.

En este sentido, hemos visto el concepto de variable y tipo de datos. Las variables son objetos que contienen información y nos permiten manipularla. La información que puede contener una variable viene determinada por su tipo de dato. Cada tipo de dato permite guardar un determinado tipo de información, y tenemos diferentes niveles de complejidad. Además, cada tipo de dato tiene un conjunto de operaciones asociadas (aritméticas, lógicas, de asignación, ...). También hemos visto que se pueden hacer cambios de un tipo de dato a otro (casts).

Los tipos básicos permiten guardar información muy básica, como un carácter, un número entero o un real. Estos tipos básicos se pueden combinar mediante tuplas para formar tipos de datos más complejas, que pueden guardar la información de una persona o un movimiento bancario.

Además, podemos guardar conjuntos de objetos. Cuando tenemos un conjunto con un número fijado de elementos, utilizamos los vectores o las matrices. Cuando tenemos un número variable de elementos, utilizamos las tablas. También tenemos los tipos abstractos de datos, muy similares a las tablas, pero que tienen un conjunto de operaciones que les otorgan propiedades especiales, como son colas, pilas y listas.

Finalmente hemos visto los punteros, que son un tipo de dato que puede almacenar una dirección de memoria. Este tipo de dato nos permiten definir parámetros de entrada y salida en acciones y funciones, y tienen un papel muy importante en el uso de la memoria dinámica.

Estructuras de control

Hemos visto que los algoritmos y programas son un conjunto de instrucciones que se ejecutan de forma secuencial. Las estructuras de control nos permiten modificar esta ejecución. Tenemos dos tipos de estructuras de control, las alternativas, que nos permiten decidir si ejecutar un código o no dependiendo de una condición lógica y las repetitivas, que nos permiten ejecutar un código varias veces. Dentro del primer conjunto tenemos las estructuras if, if-else y switch. En el segundo conjunto hemos visto las estructuras for y while. También hemos visto que para las estructuras repetitivas, existen dos casos típicos que si los identificamos nos pueden ayudar a definir la estructura (búsqueda y recorrido).

Modularidad

El concepto de modularidad hace referencia a la división del código en fragmentos más pequeños y reutilizables. Hemos visto que hay diferentes niveles de modularidad:

  • Podemos agrupar fragmentos de código en una acción o función. La diferencia es que las funciones devuelven un valor y por lo tanto se pueden utilizar como parte de una expresión, mientras que las acciones no retornan valor y por lo tanto no pueden estar en una expresión. Los parámetros de las acciones pueden ser de entrada, de salida o de entrada/salida, mientras que los parámetros de las funciones siempre serán de entrada.
  • Las funciones y acciones se pueden agrupar en ficheros. Tenemos dos tipos de ficheros, los de cabecera (*.h) y los de código (*.c).
  • Múltiples archivos se pueden agrupar en formato de librería, pudiéndose utilizar en múltiples aplicaciones. Aunque no hemos hecho nuestras propias librerías, si que hemos utilizado múltiples librerías de C, como la stdio que nos proporciona la acción scanf y printf, o la stdlib que nos proporciona las funciones malloc y free.

Memoria estática y memoria dinámica

Con los tipos de datos hemos visto que cada variable ocupa un cierto espacio en memoria. La forma en que esta memoria se reserva diferencia entre memoria estática o memoria dinámica. La memoria estática queda definida en nuestro programa, y no puede cambiar durante la ejecución del mismo. Por ejemplo, cuando definimos una variable entera, real o booleana, el espacio que ocupa está fijado, y se reserva automáticamente al ejecutar el programa. Lo mismo ocurre cuando definimos un vector o una matriz. La gran ventaja de la memoria estática es que se gestiona automáticamente, no es necesario reservarla ni liberarla, ya que el compilador se encarga de todo. El gran inconveniente lo encontramos cuando tenemos conjuntos de datos, tales como tablas o TADs, que tienen un número de elementos que puede ir variando. Si utilizamos memoria estática, debemos reservar un espacio de memoria lo suficientemente grande para que pueda guardarse todos los elementos que necesitamos, lo que obliga a poner un tamaño máximo de elementos, y acabamos utilizando más memoria de la necesaria.

La memoria dinámica es aquella memoria que pedimos explícitamente durante la ejecución del programa, mediante las llamadas a las funciones malloc o realloc. Al pedir memoria dinámica, se nos devuelve la dirección inicial del espacio que hemos pedido, y hay que guardarla en un puntero para poder acceder a ella. Hay que tener en cuenta que cuando utilizamos este tipo de memoria, nosotros (los programadores) tenemos la responsabilidad de liberar esta memoria cuando ya no la necesitamos, mediante el comando free.

Recursividad

La recursividad es una estrategia de programación que básicamente implica que un método se llame a sí mismo con el fin de resolver un problema. Hemos visto que algunos problemas son recursivos por definición, y que otros problemas pueden convertirse en recursivos. La gran ventaja de la recursividad es que cuando es aplicable, simplifica mucho los algoritmos.

Enlaces relacionados

CodeLite

Para facilitar la realización de las actividades de programación, utilizaremos igual que en Fundamentos de Programación el entorno CodeLite. Se aconseja instalar CodeLite en el ordenador, aunqué en caso de problemas, también se puede utilizar una máquina virtual para utilizarlo. En los enlaces relacionados encontraréis toda la información.

Etiquetas:
Creado por editor1 el 2018/09/12 18:41