1.1 ¿Qué es la Programación Estructurada?
La programación estructurada es una teoría orientada a mejorar la claridad, calidad y tiempo de desarrollo utilizando únicamente subrutinas o funciones. Se trata de un paradigma de programación que nació con la vocación de facilitar la vida de los programadores, sobre todo cuando estos debían abordar fases de mejora posteriores a la creación del programa, y de ordenar la forma en la que se creaba cualquier tipo de software.
Junto con la programación orientada a objetos, es uno de los paradigmas de programación más populares que ejecutan los lenguajes más potentes que seguro conoces, incluidos, entre otros, Java, C, Python y C++.
La programación estructurada surgió como alternativa al llamado "código espagueti", programas antiguos que tenían una estructura de control de flujo compleja e incomprensible debido al uso excesivo de saltos incondicionales.
1.2 Historia y personas relevantes
El teorema de Böhm y Jacopini (1966)
En 1966, los matemáticos Corrado Böhm y Giuseppe Jacopini propusieron el teorema del programa estructurado, con el que demostraron que cualquier programa puede ser escrito utilizando solo tres instrucciones de control. ¡Esto fue toda una revolución! Implicaba la construcción de programas más sencillos y más rápidos, en los que disminuía la complejidad de las pruebas y el testing para ponerlos en funcionamiento.
Edsger Dijkstra y la carta contra el GOTO (1968)
En 1968, el científico holandés Edsger Dijkstra publicó un célebre artículo que impactó en la computación moderna: "Go To Statement Considered Harmful" (La sentencia GOTO es perjudicial). Dijkstra promovió activamente el uso de lenguajes de programación estructurada, fomentando la verificación formal de programas y la eliminación de la sentencia GOTO. De hecho, Dijkstra participó en el comité que diseñó Algol 60, el primer lenguaje de programación estructurado.
Curiosidad: El artículo de Dijkstra, publicado como una carta en la revista Communications of the ACM, generó un intenso debate que duró años. Hoy en día, prácticamente ningún lenguaje moderno utiliza la sentencia GOTO como mecanismo principal de control de flujo.
1.4 Tipos de estructuras: secuencia, selección y repetición
El teorema del programa estructurado postula que, simplemente con la combinación de tres estructuras básicas, es suficiente para expresar cualquier función computable. Estas estructuras son:
1. Estructura secuencial
La estructura secuencial es la que se da de forma natural en el lenguaje, porque las sentencias se ejecutan en el orden en el que aparecen en el programa, es decir, una detrás de la otra.
Ejemplo en PSeInt (pseudocódigo):
Algoritmo EstructuraSecuencial
Escribir "Primero se ejecuta esto"
suma <- 5 + 3
Escribir "Luego esto: ", suma
Escribir "Y finalmente esto"
FinAlgoritmo
Ejemplo en Java:
// Ejemplo de estructura secuencial
System.out.println("Primero se ejecuta esto");
int suma = 5 + 3;
System.out.println("Luego esto: " + suma);
System.out.println("Y finalmente esto");
2. Estructura de selección o condicional
La estructura condicional se basa en que una sentencia o bloque de sentencias se ejecuta según el valor de una condición (expresión booleana). Permite que el programa tome decisiones y ejecute diferentes caminos.
Ejemplo en PSeInt (if-else):
Algoritmo EstructuraSeleccion
Definir nota Como Entero
nota <- 7
Si nota >= 5 Entonces
Escribir "Aprobado"
Sino
Escribir "Suspenso"
FinSi
FinAlgoritmo
Ejemplo en Java (if-else):
// Ejemplo de estructura de selección (if-else)
int nota = 7;
if (nota >= 5) {
System.out.println("Aprobado");
} else {
System.out.println("Suspenso");
}
Ejemplo en PSeInt (selección múltiple - según):
Algoritmo SeleccionMultiple
Definir dia Como Cadena
dia <- "lunes"
Segun dia Hacer
"lunes":
Escribir "Inicio de semana"
"viernes":
Escribir "Fin de semana"
De Otro Modo:
Escribir "Día entre semana"
FinSegun
FinAlgoritmo
Ejemplo en Java (switch):
// También existe la selección múltiple (switch)
String dia = "lunes";
switch (dia) {
case "lunes":
System.out.println("Inicio de semana");
break;
case "viernes":
System.out.println("Fin de semana");
break;
default:
System.out.println("Día entre semana");
}
3. Estructura de iteración (ciclo o bucle)
La estructura de repetición ejecuta una o un conjunto de sentencias mientras una condición sea verdadera. Permite repetir bloques de código de forma controlada.
Ejemplo en PSeInt (Mientras):
Algoritmo IteracionMientras
Definir contador Como Entero
contador <- 1
Mientras contador <= 5 Hacer
Escribir "Vuelta número ", contador
contador <- contador + 1
FinMientras
FinAlgoritmo
Ejemplo en Java (while):
// Ejemplo de iteración con while (condicional al inicio)
int contador = 1;
while (contador <= 5) {
System.out.println("Vuelta número " + contador);
contador++;
}
Ejemplo en PSeInt (Repetir - Hasta Que):
Algoritmo IteracionRepetir
Definir opcion Como Entero
Repetir
Escribir "Menú: pulse 1 para continuar, 0 para salir"
Leer opcion
Hasta Que opcion = 0
FinAlgoritmo
Ejemplo en Java (do-while):
// Ejemplo de do-while (condicional al final, ejecuta al menos una vez)
int opcion;
do {
System.out.println("Menú: pulse 1 para continuar, 0 para salir");
// Lectura de opcion
} while (opcion != 0);
Ejemplo en PSeInt (Para):
Algoritmo IteracionPara
Definir i Como Entero
Para i <- 1 Hasta 5 Con Paso 1 Hacer
Escribir "Valor de i: ", i
FinPara
FinAlgoritmo
Ejemplo en Java (for):
// Ejemplo de iteración con for (iteración determinada)
for (int i = 1; i <= 5; i++) {
System.out.println("Valor de i: " + i);
}
Importante: Y solamente con estas tres estructuras de control, ¡se pueden escribir todos los programas y aplicaciones posibles! Si estás pensando que los lenguajes de programación tienen más estructuras, es cierto, pero cualquiera de ellas puede ser construida gracias a estas tres básicas.
1.5 La eliminación del GOTO
Antes de la programación estructurada, era común el uso de la sentencia GOTO, que permitía saltar incondicionalmente a cualquier parte del programa. Esto provocaba:
- Código espagueti: Flujos de ejecución tan enmarañados que era imposible seguir la lógica.
- Dificultad de depuración: Los errores eran muy difíciles de rastrear.
- Mantenimiento casi imposible: Modificar una parte del programa podía tener efectos imprevisibles en otras.
La programación estructurada demostró que no se necesita GOTO si se usan correctamente las tres estructuras básicas (secuencia, selección e iteración). Hoy en día, el uso de GOTO está prácticamente desterrado de los lenguajes modernos, o se limita a casos muy específicos.
Ejemplo de "código espagueti" con GOTO (solo para entender el problema):
// ¡Esto es lo que se hacía ANTES de la programación estructurada!
10 INPUT "Introduce un número: ", N
20 IF N = 0 GOTO 60
30 IF N < 0 GOTO 80
40 PRINT "Positivo"
50 GOTO 10
60 PRINT "Es cero"
70 GOTO 10
80 PRINT "Negativo"
90 GOTO 10
Como puedes ver, el flujo del programa da saltos constantemente, haciendo muy difícil seguir la lógica. ¡Imagina un programa con cientos o miles de estas instrucciones!