2. Algoritmos
y
Estructura
de
Datos
Parte
1
de
7:
Introducción
y
conceptos
básicos
Libros
de
Wikipedia
2015
Por
Wikipedians
EDITADO
POR:
Reiner
Creutzburg,
Montserrat
Rodríguez,
Dulce
García,
María
Martínez
Fachhochschule
Brandenburg
Fachbereich
Informatik
und
Medien
PF
2132
D-‐14737
Brandenburg
,
Germany
Email:
creutzburg@fh-‐brandenburg.de
7. Capítulo 1
Computadora
Computadora personal, vista del hardware típico.
1: Monitor
2: Placa principal
3: Microprocesador o CPU
4: Puertos IDE
5: Memoria RAM
6: Placas de expansión
7: Fuente de alimentación
8: Unidad de disco óptico
9: Unidad de disco duro, Unidad de estado sólido
10: Teclado
11: Ratón
La computadora[1][2]
(del inglés: computer; y este
del latín: computare, 'calcular'), también denominada
computador[3][1]
u ordenador[4][5]
(del francés: ordina-
teur; y este del latín: ordinator), es una máquina electró-
nica que recibe y procesa datos para convertirlos en in-
formación conveniente y útil. Una computadora está for-
mada, físicamente, por numerosos circuitos integrados y
otros muchos componentes de apoyo, extensión y acce-
sorios, que en conjunto pueden ejecutar tareas diversas
con suma rapidez y bajo el control de un programa.
Dos partes esenciales la constituyen, el hardware, que es
su composición física (circuitos electrónicos, cables, ga-
binete, teclado, etcétera) y su software, siendo ésta la par-
Computadora de Escritorio.
Fuente de alimentación.
te intangible (programas, datos, información, etcétera).
Una no funciona sin la otra.
Desde el punto de vista funcional es una máquina que po-
see, al menos, una unidad central de procesamiento, una
memoria principal y algún periférico o dispositivo de en-
trada y otro de salida. Los dispositivos de entrada permi-
ten el ingreso de datos, la CPU se encarga de su procesa-
miento (operaciones arimético-lógicas) y los dispositivos
de salida los comunican a otros medios. Es así, que la
computadora recibe datos, los procesa y emite la infor-
mación resultante, la que luego puede ser interpretada,
almacenada, transmitida a otra máquina o dispositivo o
1
8. 2 CAPÍTULO 1. COMPUTADORA
sencillamente impresa; todo ello a criterio de un opera-
dor o usuario y bajo el control de un programa.
El hecho de que sea programable, le posibilita realizar
una gran diversidad de tareas, ésto la convierte en una
máquina de propósitos generales (a diferencia, por ejem-
plo, de una calculadora cuyo único propósito es calcular
limitadamente). Es así que, en base a datos de entrada,
puede realizar operaciones y resolución de problemas en
las más diversas áreas del quehacer humano (administra-
tivas, científicas, de diseño, ingeniería, medicina, comu-
nicaciones, música, etc), incluso muchas cuestiones que
directamente no serían resolubles o posibles sin su inter-
vención.
Básicamente, la capacidad de una computadora depende
de sus componentes hardware, en tanto que la diversidad
de tareas radica mayormente en el software que admita
ejecutar y contenga instalado.
Si bien esta máquina puede ser de dos tipos diferentes,
analógica o digital, el primer tipo es usado para pocos y
muy específicos propósitos; la más difundida, utilizada
y conocida es la computadora digital (de propósitos ge-
nerales); de tal modo que en términos generales (incluso
populares), cuando se habla de “la computadora” se está
refiriendo a computadora digital. Las hay de arquitectura
mixta, llamadas computadoras híbridas, siendo también
éstas de propósitos especiales.
En la Segunda Guerra mundial se utilizaron
computadoras analógicas mecánicas, orientadas a
aplicaciones militares, y durante la misma se desarrolló
la primera computadora digital, que se llamó ENIAC;
ella ocupaba un enorme espacio y consumía grandes
cantidades de energía, que equivalen al consumo de
cientos de computadores actuales (PC’s).[6]
Los compu-
tadores modernos están basados en circuitos integrados,
miles de millones de veces más veloces que las primeras
máquinas, y ocupan una pequeña fracción de su espacio.
[7]
Computadoras simples son lo suficientemente peque-
ñas para residir en los dispositivos móviles. Las
computadoras portátiles, tales como tabletas, netbooks,
notebooks, ultrabooks, pueden ser alimentadas por pe-
queñas baterías. Computadoras personales en sus diver-
sas formas son iconos de la Era de la información y son
lo que la mayoría de la gente considera como “compu-
tadoras”. Sin embargo, los computadores integrados se
encuentran en muchos dispositivos actuales, tales como
reproductores MP4; teléfonos celulares; aviones de com-
bate, y, desde juguetes hasta robot industriales.
1.1 Componentes
Las tecnologías utilizadas en computadoras digitales han
evolucionado mucho desde la aparición de los primeros
modelos en los años 1940, aunque la mayoría todavía uti-
liza la Arquitectura de von Neumann, publicada por John
Modelo básico de la arquitectura de von Neumann, en la que se
basan todos los ordenadores modernos.
von Neumann a principios de esa década, que otros auto-
res atribuyen a John Presper Eckert y John William Mau-
chly.
La arquitectura de Von Neumann describe una compu-
tadora con cuatro (4) secciones principales: la unidad arit-
mético lógica, la unidad de control, la memoria primaria,
principal o central, y los dispositivos de entrada y salida
(E/S). Estas partes están interconectadas por canales de
conductores denominados buses.
1.1.1 Unidad central de procesamiento
La unidad central de procesamiento (CPU, por sus si-
glas del inglés: Central Processing Unit) consta de manera
básica de los siguientes tres elementos:
A B
F D
R
Un típico símbolo esquemático para una ALU: A y B son ope-
randos; R es la salida; F es la entrada de la unidad de control;
D es un estado de la salida.
• La unidad aritmético lógica (ALU, por sus siglas
del inglés: Arithmetic-Logic Unit) es el dispositivo
diseñado y construido para llevar a cabo las opera-
ciones elementales como las operaciones aritméticas
(suma, resta, ...), operaciones lógicas (Y, O, NO), y
operaciones de comparación o relacionales. En esta
unidad es en donde se hace todo el trabajo compu-
tacional.
9. 1.2. OTROS CONCEPTOS 3
• La unidad de control (UC) sigue la dirección de las
posiciones en memoria que contienen la instrucción
que el computador va a realizar en ese momento;
recupera la información poniéndola en la ALU para
la operación que debe desarrollar. Transfiere luego
el resultado a ubicaciones apropiadas en la memoria.
Una vez que ocurre lo anterior, la unidad de control
va a la siguiente instrucción (normalmente situada en
la siguiente posición, a menos que la instrucción sea
una instrucción de salto, informando al ordenador
de que la próxima instrucción estará ubicada en otra
posición de la memoria).
• Los registros: de datos, de memoria, registros cons-
tantes, de coma flotante, de propósito general, de
propósito específico.
Los procesadores pueden constar de además de las ante-
riormente citadas, de otras unidades adicionales como la
unidad de coma flotante.
1.1.2 Memoria primaria
La memoria principal (MP), conocida como memoria
de acceso aleatorio (RAM, por sus siglas del inglés:
Random-Access Memory), es una secuencia de celdas de
almacenamiento numeradas, donde cada una es un bit o
unidad de información. La instrucción es la información
necesaria para realizar lo que se desea con el computador.
Las «celdas» contienen datos que se necesitan para llevar
a cabo las instrucciones, con el computador. El número
de celdas varían mucho de computador a computador, y
las tecnologías empleadas para la memoria han cambiado
bastante; van desde los relés electromecánicos, tubos lle-
nos de mercurio en los que se formaban los pulsos acústi-
cos, matrices de imanes permanentes, transistores indivi-
duales a circuitos integrados con millones de celdas en un
solo chip se subdividen en memoria estática (SRAM) con
seis transistores por bit y la mucho más utilizada memoria
dinámica (DRAM) un transistor y un condensador por
bit. En general, la memoria puede ser reescrita varios mi-
llones de veces (memoria RAM); se parece más a una pi-
zarra que a una lápida (memoria ROM) que sólo puede
ser escrita una vez.
1.1.3 Periféricos de Entrada, de Salida o
de Entrada/Salida
Los dispositivos de Entrada/Salida (E/S) sirven a la
computadora para obtener información del mundo ex-
terior y/o comunicar los resultados generados por el
computador al exterior. Hay una gama muy extensa de
dispositivos E/S como teclados, monitores, unidades de
disco flexible o cámaras web.
1.1.4 Buses
Las tres unidades básicas en una computadora: la CPU,
la MP y el subsistema de E/S, están comunicadas entre sí
por buses o canales de comunicación:
• Bus de direcciones, para seleccionar la dirección del
dato o del periférico al que se quiere acceder,
• Bus de control, básicamente para seleccionar la ope-
ración a realizar sobre el dato (principalmente lec-
tura, escritura o modificación) y
• Bus de datos, por donde circulan los datos.
1.2 Otros conceptos
En la actualidad se puede tener la impresión de que los
computadores están ejecutando varios programas al mis-
mo tiempo. Esto se conoce como multitarea, y es más
común que se utilice el segundo término. En realidad, la
CPU ejecuta instrucciones de un programa y después tras
un breve periodo de tiempo, cambian a un segundo pro-
grama y ejecuta algunas de sus instrucciones. Esto crea
la ilusión de que se están ejecutando varios programas
simultáneamente, repartiendo el tiempo de la CPU en-
tre los programas. Esto es similar a la película que está
formada por una sucesión rápida de fotogramas. El siste-
ma operativo es el programa que generalmente controla
el reparto del tiempo. El procesamiento simultáneo viene
con computadoras de más de un CPU, lo que da origen
al multiprocesamiento.
El sistema operativo es una especie de caja de herramien-
tas llena de utilerías que sirven para decidir, por ejemplo,
qué programas se ejecutan, y cuándo, y qué fuentes se
utilizan (memoria o dispositivos E/S). El sistema opera-
tivo tiene otras funciones que ofrecer a otros programas,
como los códigos que sirven a los programadores, escri-
bir programas para una máquina sin necesidad de conocer
los detalles internos de todos los dispositivos electrónicos
conectados.
A 2015 se están empezando a incluir en las distribuciones
donde se incluye el sistema operativo, algunos programas
muy usados, debido a que es ésta una manera económica
de distribuirlos. No es extraño que un sistema operativo
incluya navegadores de Internet, procesadores de texto,
programas de correo electrónico, interfaces de red, re-
productores de películas y otros programas que antes se
tenían que conseguir e instalar separadamente.
Los primeros computadores digitales, de gran tamaño y
coste, se utilizaban principalmente para hacer cálculos
científicos. ENIAC, uno de los primeros computadores,
calculaba densidades de neutrón transversales para ver si
explotaría la bomba de hidrógeno. El CSIR Mk I, el pri-
mer ordenador australiano, evaluó patrones de precipita-
ciones para un gran proyecto de generación hidroeléctri-
10. 4 CAPÍTULO 1. COMPUTADORA
ca. Los primeros visionarios vaticinaron que la progra-
mación permitiría jugar al ajedrez, ver películas y otros
usos.
La gente que trabajaba para los gobiernos y las grandes
empresas también usó los computadores para automati-
zar muchas de las tareas de recolección y procesamiento
de datos, que antes eran hechas por humanos; por ejem-
plo, mantener y actualizar la contabilidad y los inventa-
rios. En el mundo académico, los científicos de todos los
campos empezaron a utilizar los computadores para ha-
cer sus propios análisis. El descenso continuo de los pre-
cios de los computadores permitió su uso por empresas
cada vez más pequeñas. Las empresas, las organizacio-
nes y los gobiernos empezaron a emplear un gran número
de pequeños computadores para realizar tareas que antes
eran hechas por computadores centrales grandes y costo-
sos. La reunión de varios pequeños computadores en un
solo lugar se llamaba torre de servidores[cita requerida]
.
Con la invención del microprocesador en 1970, fue
posible fabricar computadores muy baratos. Nacen los
computadores personales (PC), los que se hicieron famo-
sos para llevar a cabo diferentes tareas como guardar li-
bros, escribir e imprimir documentos, calcular probabi-
lidades y otras tareas matemáticas repetitivas con hojas
de cálculo, comunicarse mediante correo electrónico e
Internet. Sin embargo, la gran disponibilidad de compu-
tadores y su fácil adaptación a las necesidades de cada
persona, han hecho que se utilicen para varios propósi-
tos.
Al mismo tiempo, los pequeños computadores fueron ca-
si siempre con una programación fija, empezaron a hacer-
se camino entre las aplicaciones del hogar, los coches, los
aviones y la maquinaria industrial. Estos procesadores in-
tegrados controlaban el comportamiento de los aparatos
más fácilmente, permitiendo el desarrollo de funciones
de control más complejas como los sistemas de freno an-
tibloqueo en los coches. A principios del siglo XXI, la
mayoría de los aparatos eléctricos, casi todos los tipos
de transporte eléctrico y la mayoría de las líneas de pro-
ducción de las fábricas funcionan con un computador. La
mayoría de los ingenieros piensa que esta tendencia va a
continuar.
Hacia finales de siglo XX y comienzos del XXI, los
computadores personales son usados tanto para la investi-
gación como para el entretenimiento (videojuegos), pero
los grandes computadores aún sirven para cálculos mate-
máticos complejos y para otros usos de la ciencia, tecno-
logía, astronomía, medicina, etc.
Tal vez el más interesante “descendiente” del cruce entre
el concepto de la PC o computadora personal y los llama-
dos supercomputadores sea la Workstation o estación de
trabajo. Este término, originalmente utilizado para equi-
pos y máquinas de registro, grabación y tratamiento di-
gital de sonido, y ahora utilizado precisamente en refe-
rencia a estaciones de trabajo (traducido literalmente del
inglés), se usa para dar nombre a equipos que, debido so-
bre todo a su utilidad dedicada especialmente a labores
de cálculo científico, eficiencia contra reloj y accesibili-
dad del usuario bajo programas y software profesional y
especial, permiten desempeñar trabajos de gran cantidad
de cálculos y “fuerza” operativa. Una Workstation es, en
esencia, un equipo orientado a trabajos personales, con
capacidad elevada de cálculo y rendimiento superior a los
equipos PC convencionales, que aún tienen componentes
de elevado coste, debido a su diseño orientado en cuanto
a la elección y conjunción sinérgica de sus componentes.
En estos casos, el software es el fundamento del diseño
del equipo, el que reclama, junto con las exigencias del
usuario, el diseño final de la Workstation.[cita requerida]
1.3 Etimología de la palabra orde-
nador
PC con interfaz táctil.
La palabra española ordenador proviene del término
francés ordinateur, en referencia a Dios que pone orden
en el mundo (“Dieu qui met de l'ordre dans le monde”).[8]
En parte por cuestiones de marketing, puesto que la des-
cripción realizada por IBM para su introducción en Fran-
cia en 1954 situaba las capacidades de actuación de la má-
quina cerca de la omnipotencia, idea equivocada que per-
dura hoy en día al considerar que la máquina universal de
Turing es capaz de computar absolutamente todo.[9]
En
1984, académicos franceses reconocieron, en el debate
Les jeunes, la technique et nous, que el uso de este sustan-
tivo es incorrecto, porque la función de un computador
es procesar datos, no dar órdenes.[10]
Mientras que otros,
como el catedrático de filología latina Jacques Perret, co-
nocedores del origen religioso del término, lo consideran
más correcto que las alternativas.[8]
El uso de la palabra ordinateur se ha exportado a los
idiomas de España: el aragonés, el asturiano, el gallego, el
castellano, el catalán y el euskera. El español que se habla
en Iberoamérica, así como los demás idiomas europeos,
como el portugués, el alemán y el neerlandés, utilizan tér-
minos derivados de computare.
11. 1.4. VÉASE TAMBIÉN 5
1.4 Véase también
• Portal:Informática. Contenido relacionado con
Informática.
• Hardware
• Software
• Firmware
1.4.1 Historia
• Anexo:Historia de la computación
• Historia del hardware
• Historia del hardware de computadora (1960-
presente)
• Historia de las computadoras personales
1.4.2 Tipos de computadoras
• Computadora analógica
• Computadora híbrida
• Supercomputadora
• Computadora central
• Minicomputadora
• Microcomputadora
• Computadora de escritorio
• Computadora personal
• Computadora doméstica
• Multiseat
• Computadora portátil
• Tableta (computadora)
• Subportátil
• PC Ultra Móvil
• PDA
• Teléfono inteligente
• Tabléfono
• Cliente (informática)
• Cliente liviano
• Cliente pesado
• Cliente híbrido
• Sistema embebido
1.4.3 Componentes y periféricos
• Placa base
• Unidad central de procesamiento
• Microprocesador
• BIOS
• Memoria de acceso aleatorio
• Memoria de solo lectura
• Memoria flash
• Bus (informática)
• Entrada/salida
• Fuente eléctrica
• Fuente de alimentación
• Teclado
• Ratón (informática)
• Touchpad
• Lápiz óptico
• Pantalla táctil
• Tableta digitalizadora
• Monitor
• Impresora
• Tarjeta de sonido
• Tarjeta gráfica
• Unidad de procesamiento gráfico
• Disco duro
• Disquete
• CD-ROM
• DVD
1.4.4 Otros
• Caja de computadora
• Puerto serie
• Puerto paralelo
• PS/2 (puerto)
• Universal Serial Bus
• IEEE 1394
• Tarjeta de red
12. 6 CAPÍTULO 1. COMPUTADORA
• Peripheral Component Interconnect
• Hardware
• Software
• Programa informático
• Aplicación informática
• Sistema operativo
• Sistema de archivos
• Internet
• Virtualización
• World Wide Web
1.5 Referencias
[1] «computadora», Diccionario de la lengua española (22.ª
edición), Real Academia Española, 2001, http://lema.rae.
es/drae/srv/search?key=computadora, consultado el 8 de
abril de 2015.
[2] «computadora» en Diccionario panhispánico de dudas, 1.ª
ed., Real Academia Española y Asociación de Academias
de la Lengua Española, 2005, consultado el 8 de abril de
2015.
[3] «computador», Diccionario de la lengua española (22.ª
edición), Real Academia Española, 2001, http://lema.rae.
es/drae/srv/search?key=computador, consultado el 8 de
abril de 2015.
[4] «ordenador», Diccionario de la lengua española (22.ª edi-
ción), Real Academia Española, 2001, http://lema.rae.es/
drae/srv/search?key=ordenador, consultado el 8 de abril
de 2015.
[5] «ordenador» en Diccionario panhispánico de dudas, 1.ª
ed., Real Academia Española y Asociación de Academias
de la Lengua Española, 2005, consultado el 8 de abril de
2015.
[6] En 1946, ENIAC requería alrededor de 174 kW. En com-
paración, una laptop moderna consume alrededor de 30
W; cerca de seis mil veces menos. «Approximate Desktop
& Notebook Power Usage». University of Pennsylvania.
Consultado el 29 de julio de 2014.
[7] Las primeras computadoras tales como Colossus y
ENIAC eran capaces de procesar entre 5 y 100 opera-
ciones por segundo. Un moderno microprocesador puede
procesar miles de millones de operaciones por segundo, y
muchas de estas operaciones son bastante más complejas
que en sus predecesoras. «Intel Core I7 Processor: Featu-
res». Intel Corporation. Consultado el 29 de julio de 2014.
[8] Etimología de la palabra ordenador (en francés).
[9] Ben-Amram, Amir M. (2005). «The Church-Turing the-
sis and its look-alikes». SIGACT News 36 (3): 113–114.
doi:10.1145/1086649.1086651. Consultado el 8 de no-
viembre de 2009.
[10] El uso de la palabra ordenador. El Mundo.es.
1.6 Enlaces externos
• Wikimedia Commons alberga contenido multi-
media sobre ComputadoraCommons.
• Wikcionario tiene definiciones y otra informa-
ción sobre computador.Wikcionario
• Wikiquote alberga frases célebres de o sobre
Computadora. Wikiquote
• Wikilibro de Montaje y Mantenimiento de
Equipos Informáticos.
• El Diccionario de la Real Academia Española tiene
una definición para computador.
• Información sobre qué es una computadora, en mo-
nografías.com
13. Capítulo 2
Ciencias de la información (tecnología)
Las ciencias de la información (information science en
inglés) es una rama de la ciencia que estudia la práctica
del procesamiento de información y la ingeniería de los
sistemas de información. Tiene un fuerte vínculo con las
ciencias de la computación.
El campo estudia la estructura, algoritmos, comporta-
miento e interacciones de los sistemas naturales y arti-
ficiales que guardan, procesan, acceden a y comunican
información. También desarrolla sus propios fundamen-
tos conceptuales y teóricos y emplea fundamentos desa-
rrollados en otros campos.
En Ciencias de la Información, constituyen temas clave el
estudio de los conceptos dato, información, conocimiento
y sabiduría, a los cuales se los suele organizar bajo la for-
ma de una pirámide de menor a mayor complejidad, ubi-
cándose la sabiduría en el vértice, y los datos en la base.
Como ejemplo, la altura de una montaña sería un dato,
y cuando se lo combina con otros datos, como por ejem-
plo la temperatura media, la presión atmosférica, hume-
dad, etc., constituye información, en este caso informa-
ción meteorológica sobre el estado de la montaña, que
permite definir si el clima es “favorable” o “desfavorable”
para el ascenso. Cuando continuamos agregando grados
de abstracción, llegamos al “conocimiento”, que permi-
te la toma de decisiones apropiadas para lograr un cierto
fin. Como ejemplo, a pesar de tener una condición me-
teorológica favorable para el ascenso, alguien con cono-
cimiento en el ascenso a montañas, tiene que integrar in-
formación de otras fuentes, como por ejemplo saber si
se cuenta con el equipo y entrenamiento apropiado para
el ascenso, etc. Si a este conocimiento específico agrega-
mos un elemento de buena intención y consideración de
abstracciones más abarcativas o completas, como tener
en cuenta si el realizar este ascenso producirá un efec-
to positivo en la generación venidera de jóvenes, o por
el contrario, los alentará a realizar actividades riesgosas,
etc. podremos hablar de “sabiduria”, que se refleja en la
toma de decisiones acertadas, que producen un beneficio
mayor sobre un potencial perjuicio.
Desde la llegada de los ordenadores, los individuos y las
organizaciones cada vez más procesan la información de
manera digital. Esto ha llevado al estudio de la informa-
ción que tiene aspectos computacionales, cognitivos y so-
ciales, incluyendo el estudio del impacto social de las tec-
nologías de la información.
7
14. Capítulo 3
Lenguaje de programación
Captura de la microcomputadora Commodore PET-32 mostran-
do un programa en el lenguaje de programación BASIC, bajo el
emulador VICE en una distribución GNU/Linux.
Un ejemplo de código fuente escrito en el lenguaje de programa-
ción Java, que imprimirá el mensaje “Hello World!" a la salida
estándar cuando es compilado y ejecutado
Un lenguaje de programación es un lenguaje formal di-
señado para expresar procesos que pueden ser llevados a
cabo por máquinas como las computadoras.
Pueden usarse para crear programas que controlen el
comportamiento físico y lógico de una máquina, para ex-
presar algoritmos con precisión, o como modo de comu-
nicación humana.[1]
Está formado por un conjunto de símbolos y reglas
sintácticas y semánticas que definen su estructura y el sig-
nificado de sus elementos y expresiones. Al proceso por
el cual se escribe, se prueba, se depura, se compila (de ser
necesario) y se mantiene el código fuente de un programa
informático se le llama programación.
También la palabra programación se define como el pro-
ceso de creación de un programa de computadora, me-
diante la aplicación de procedimientos lógicos, a través
de los siguientes pasos:
• El desarrollo lógico del programa para resolver un
problema en particular.
• Escritura de la lógica del programa empleando un
lenguaje de programación específico (codificación
del programa).
• Ensamblaje o compilación del programa hasta con-
vertirlo en lenguaje de máquina.
• Prueba y depuración del programa.
• Desarrollo de la documentación.
Existe un error común que trata por sinónimos los térmi-
nos 'lenguaje de programación' y 'lenguaje informático'.
Los lenguajes informáticos engloban a los lenguajes de
programación y a otros más, como por ejemplo HTML
(lenguaje para el marcado de páginas web que no es pro-
piamente un lenguaje de programación, sino un conjunto
de instrucciones que permiten estructurar el contenido de
los documentos).
Permite especificar de manera precisa sobre qué datos de-
be operar una computadora, cómo deben ser almacena-
dos o transmitidos y qué acciones debe tomar bajo una
variada gama de circunstancias. Todo esto, a través de un
lenguaje que intenta estar relativamente próximo al len-
guaje humano o natural. Una característica relevante de
los lenguajes de programación es precisamente que más
de un programador pueda usar un conjunto común de ins-
trucciones que sean comprendidas entre ellos para reali-
zar la construcción de un programa de forma colaborati-
va.
3.1 Historia
Para que la computadora entienda nuestras instrucciones
debe usarse un lenguaje específico conocido como código
máquina, el cual la máquina comprende fácilmente, pero
que lo hace excesivamente complicado para las personas.
De hecho sólo consiste en cadenas extensas de números
0 y 1.
Para facilitar el trabajo, los primeros operadores de
computadoras decidieron hacer un traductor para reem-
plazar los 0 y 1 por palabras o abstracción de palabras
8
15. 3.2. ELEMENTOS 9
Código Fortran en una tarjeta perforada, mostrando el uso espe-
cializado de las columnas 1-5, 6 y 73-80.
y letras provenientes del inglés; éste se conoce como
lenguaje ensamblador. Por ejemplo, para sumar se usa la
letra A de la palabra inglesa add (sumar). El lenguaje en-
samblador sigue la misma estructura del lenguaje máqui-
na, pero las letras y palabras son más fáciles de recordar
y entender que los números.
La necesidad de recordar secuencias de programación pa-
ra las acciones usuales llevó a denominarlas con nombres
fáciles de memorizar y asociar: ADD (sumar), SUB (res-
tar), MUL (multiplicar), CALL (ejecutar subrutina), etc.
A esta secuencia de posiciones se le denominó “instruc-
ciones”, y a este conjunto de instrucciones se le llamó
lenguaje ensamblador. Posteriormente aparecieron dife-
rentes lenguajes de programación, los cuales reciben su
denominación porque tienen una estructura sintáctica si-
milar a los lenguajes escritos por los humanos, denomi-
nados también lenguajes de alto nivel.
La primera programadora de computadora conocida fue
Ada Lovelace, hija de Anabella Milbanke Byron y Lord
Byron. Anabella introdujo en las matemáticas a Ada
quien, después de conocer a Charles Babbage, tradujo y
amplió una descripción de su máquina analítica. Incluso
aunque Babbage nunca completó la construcción de cual-
quiera de sus máquinas, el trabajo que Ada realizó con
éstas le hizo ganarse el título de primera programadora
de computadoras del mundo. El nombre del lenguaje de
programación Ada fue escogido como homenaje a esta
programadora.
A finales de 1953, John Backus sometió una propues-
ta a sus superiores en IBM para desarrollar una alter-
nativa más práctica al lenguaje ensamblador para pro-
gramar la computadora central IBM 704. El histórico
equipo Fortran de Backus consistió en los programado-
res Richard Goldberg, Sheldon F. Best, Harlan Herrick,
Peter Sheridan, Roy Nutt, Robert Nelson, Irving Ziller,
Lois Haibt y David Sayre.[2]
El primer manual para el lenguaje Fortran apareció en oc-
tubre de 1956, con el primer compilador Fortran entrega-
do en abril de 1957. Esto era un compilador optimizado,
porque los clientes eran reacios a usar un lenguaje de alto
nivel a menos que su compilador pudiera generar código
cuyo desempeño fuera comparable al de un código hecho
a mano en lenguaje ensamblador.
En 1960, se creó COBOL, uno de los lenguajes usados
aún en la actualidad, en informática de gestión.
A medida que la complejidad de las tareas que realizaban
las computadoras aumentaba, se hizo necesario disponer
de un método más eficiente para programarlas. Entonces,
se crearon los lenguajes de alto nivel, como lo fue BASIC
en las versiones introducidas en los microordenadores de
la década de 1980. Mientras que una tarea tan sencilla
como sumar dos números puede necesitar varias instruc-
ciones en lenguaje ensamblador, en un lenguaje de alto
nivel bastará una sola sentencia.
3.2 Elementos
3.2.1 Variables y vectores
Imagen tomada de Pauscal, lenguaje de programación en espa-
ñol creado en Argentina.
Las variables podrían calificarse como contenedores de
datos y por ello se diferencian según el tipo de dato que
son capaces de almacenar. En la mayoría de lenguajes de
programación se requiere especificar un tipo de variable
concreto para guardar un dato concreto. Por ejemplo, en
Java, si deseamos guardar una cadena de texto debere-
mos especificar que la variable es del tipo String. Por otra
parte, en lenguajes como el PHP este tipo de especifica-
ción de variables no es necesario. Además, existen varia-
bles compuestas por varias variables llamadas vectores.
Un vector no es más que un conjunto de variables conse-
cutivas en memoria y del mismo tipo guardadas dentro de
una variable contenedor. A continuación, un listado con
los tipos de variables y vectores más comunes:
• Variables tipo Char: Estas variables contienen un
único carácter, es decir, una letra, un signo o un nú-
mero.
• Variables tipo Int: Contienen un número entero.
• Variables tipo float: Contienen un número decimal.
• Variables tipo String: Contienen cadenas de texto, o
lo que es lo mismo, es un vector con varias variables
del tipo Char.
16. 10 CAPÍTULO 3. LENGUAJE DE PROGRAMACIÓN
• Variables del tipo Boolean: Solo pueden contener un
0 o un 1. El cero es considerado para muchos len-
guajes como el literal “False”, mientras que el 1 se
considera “True”.
3.2.2 Condicionantes
Los condicionantes son estructuras de código que indican
que, para que cierta parte del programa se ejecute, deben
cumplirse ciertas premisas; por ejemplo: que dos valores
sean iguales, que un valor exista, que un valor sea ma-
yor que otro... Estos condicionantes por lo general solo
se ejecutan una vez a lo largo del programa. Los condi-
cionantes más conocidos y empleados en programación
son:
• If: Indica una condición para que se ejecute una par-
te del programa.
• Else if: Siempre va precedido de un “If” e indica una
condición para que se ejecute una parte del progra-
ma siempre que no cumpla la condición del if previo
y si se cumpla con la que el “else if” especifique.
• Else: Siempre precedido de “If” y en ocasiones de
“Else If”. Indica que debe ejecutarse cuando no se
cumplan las condiciones prévias.
3.2.3 Bucles
Los bucles son parientes cercanos de los condicionan-
tes, pero ejecutan constantemente un código mientras se
cumpla una determinada condición. Los más frecuentes
son:
• For: Ejecuta un código mientras una variable se en-
cuentre entre 2 determinados parámetros.
• While: Ejecuta un código mientras que se cumpla la
condición que solicita.
Hay que decir que a pesar de que existan distintos tipos
de bucles, ambos son capaces de realizar exactamente las
mismas funciones. El empleo de uno u otro depende, por
lo general, del gusto del programador.
3.2.4 Funciones
Las funciones se crearon para evitar tener que repetir
constantemente fragmentos de código. Una función po-
dría considerarse como una variable que encierra código
dentro de si. Por lo tanto cuando accedemos a dicha va-
riable (la función) en realidad lo que estamos haciendo es
ordenar al programa que ejecute un determinado código
predefinido anteriormente.
Todos los lenguajes de programación tienen algunos ele-
mentos de formación primitivos para la descripción de
los datos y de los procesos o transformaciones aplicadas
a estos datos (tal como la suma de dos números o la selec-
ción de un elemento que forma parte de una colección).
Estos elementos primitivos son definidos por reglas sin-
tácticas y semánticas que describen su estructura y signi-
ficado respectivamente.
3.2.5 Sintaxis
def add5(x):
return x+5
def dotwrite(ast):
nodename = getNodename()
label=symbol.sym_name.get(int(ast[0]),ast[0])
print ' %s [label="%s' % (nodename, label),
if isinstance(ast[1], str):
if ast[1].strip():
print '= %s"];' % ast[1]
else:
print '"]'
else:
print '"];'
children = []
for n, child in enumerate(ast[1:]):
children.append(dotwrite(child))
print ' %s -> {' % nodename,
for name in children:
print '%s' % name,
Con frecuencia se resaltan los elementos de la sintaxis con colores
diferentes para facilitar su lectura. Este ejemplo está escrito en
Python.
A la forma visible de un lenguaje de programación se
le conoce como sintaxis. La mayoría de los lenguajes
de programación son puramente textuales, es decir, uti-
lizan secuencias de texto que incluyen palabras, números
y puntuación, de manera similar a los lenguajes naturales
escritos. Por otra parte, hay algunos lenguajes de progra-
mación que son más gráficos en su naturaleza, utilizan-
do relaciones visuales entre símbolos para especificar un
programa.
La sintaxis de un lenguaje de programación describe las
combinaciones posibles de los símbolos que forman un
programa sintácticamente correcto. El significado que se
le da a una combinación de símbolos es manejado por su
semántica (ya sea formal o como parte del código duro de
la referencia de implementación). Dado que la mayoría de
los lenguajes son textuales, este artículo trata de la sintaxis
textual.
La sintaxis de los lenguajes de programación es defini-
da generalmente utilizando una combinación de expre-
siones regulares (para la estructura léxica) y la Notación
de Backus-Naur (para la estructura gramática). Este es
un ejemplo de una gramática simple, tomada de Lisp:
expresión ::= átomo | lista átomo ::= número | símbolo
número ::= [+-]? ['0'-'9']+ símbolo ::= ['A'-'Z'] ['a'-'z'].*
lista ::= '(' expresión* ')'
Con esta gramática se especifica lo siguiente:
17. 3.2. ELEMENTOS 11
• una expresión puede ser un átomo o una lista;
• un átomo puede ser un número o un símbolo;
• un número es una secuencia continua de uno o más
dígitos decimales, precedido opcionalmente por un
signo más o un signo menos;
• un símbolo es una letra seguida de cero o más carac-
teres (excluyendo espacios); y
• una lista es un par de paréntesis que abren y cierran,
con cero o más expresiones en medio.
Algunos ejemplos de secuencias bien formadas de acuer-
do a esta gramática:
'12345', '()', '(a b c232 (1))'
No todos los programas sintácticamente correctos son se-
mánticamente correctos. Muchos programas sintáctica-
mente correctos tienen inconsistencias con las reglas del
lenguaje; y pueden (dependiendo de la especificación del
lenguaje y la solidez de la implementación) resultar en un
error de traducción o ejecución. En algunos casos, tales
programas pueden exhibir un comportamiento indefini-
do. Además, incluso cuando un programa está bien defi-
nido dentro de un lenguaje, todavía puede tener un signi-
ficado que no es el que la persona que lo escribió estaba
tratando de construir.
Usando el lenguaje natural, por ejemplo, puede no ser po-
sible asignarle significado a una oración gramaticalmente
válida o la oración puede ser falsa:
• “Las ideas verdes y descoloridas duermen furiosa-
mente” es una oración bien formada gramaticalmen-
te pero no tiene significado comúnmente aceptado.
• “Juan es un soltero casado” también está bien for-
mada gramaticalmente pero expresa un significado
que no puede ser verdadero.
El siguiente fragmento en el lenguaje C es sintácticamen-
te correcto, pero ejecuta una operación que no está defi-
nida semánticamente (dado que p es un apuntador nulo,
las operaciones p->real y p->im no tienen ningún signifi-
cado):
complex *p = NULL; complex abs_p = sqrt (p->real *
p->real + p->im * p->im);
Si la declaración de tipo de la primera línea fuera omiti-
da, el programa dispararía un error de compilación, pues
la variable “p” no estaría definida. Pero el programa sería
sintácticamente correcto todavía, dado que las declara-
ciones de tipo proveen información semántica solamente.
La gramática necesaria para especificar un lenguaje de
programación puede ser clasificada por su posición en la
Jerarquía de Chomsky. La sintaxis de la mayoría de los
lenguajes de programación puede ser especificada utili-
zando una gramática Tipo-2, es decir, son gramáticas li-
bres de contexto. Algunos lenguajes, incluyendo a Perl y
a Lisp, contienen construcciones que permiten la ejecu-
ción durante la fase de análisis. Los lenguajes que permi-
ten construcciones que permiten al programador alterar
el comportamiento de un analizador hacen del análisis de
la sintaxis un problema sin decisión única, y generalmen-
te oscurecen la separación entre análisis y ejecución. En
contraste con el sistema de macros de Lisp y los bloques
BEGIN de Perl, que pueden tener cálculos generales, las
macros de C son meros reemplazos de cadenas, y no re-
quieren ejecución de código.
3.2.6 Semántica estática
La semántica estática define las restricciones sobre la es-
tructura de los textos válidos que resulta imposible o muy
difícil expresar mediante formalismos sintácticos están-
dar. Para los lenguajes compilados, la semántica estáti-
ca básicamente incluye las reglas semánticas que se pue-
den verificar en el momento de compilar. Por ejemplo el
chequeo de que cada identificador sea declarado antes de
ser usado (en lenguajes que requieren tales declaracio-
nes) o que las etiquetas en cada brazo de una estructu-
ra case sean distintas. Muchas restricciones importantes
de este tipo, como la validación de que los identificado-
res sean usados en los contextos apropiados (por ejemplo
no sumar un entero al nombre de una función), o que las
llamadas a subrutinas tengan el número y tipo de pará-
metros adecuado, puede ser implementadas definiéndo-
las como reglas en una lógica conocida como sistema de
tipos. Otras formas de análisis estáticos, como los análisis
de flujo de datos, también pueden ser parte de la semánti-
ca estática. Otros lenguajes de programación como Java y
C# tienen un análisis definido de asignaciones, una forma
de análisis de flujo de datos, como parte de su semántica
estática.
3.2.7 Sistema de tipos
Un sistema de tipos define la manera en la cual un lengua-
je de programación clasifica los valores y expresiones en
tipos, cómo pueden ser manipulados dichos tipos y cómo
interactúan. El objetivo de un sistema de tipos es verificar
y normalmente poner en vigor un cierto nivel de exactitud
en programas escritos en el lenguaje en cuestión, detec-
tando ciertas operaciones inválidas. Cualquier sistema de
tipos decidible tiene sus ventajas y desventajas: mientras
por un lado rechaza muchos programas incorrectos, tam-
bién prohíbe algunos programas correctos aunque poco
comunes. Para poder minimizar esta desventaja, algunos
lenguajes incluyen lagunas de tipos, conversiones explíci-
tas no checadas que pueden ser usadas por el programa-
dor para permitir explícitamente una operación normal-
mente no permitida entre diferentes tipos. En la mayoría
de los lenguajes con tipos, el sistema de tipos es usado
18. 12 CAPÍTULO 3. LENGUAJE DE PROGRAMACIÓN
solamente para checar los tipos de los programas, pero
varios lenguajes, generalmente funcionales, llevan a cabo
lo que se conoce como inferencia de tipos, que le quita al
programador la tarea de especificar los tipos. Al diseño y
estudio formal de los sistemas de tipos se le conoce como
teoría de tipos.
Lenguajes tipados versus lenguajes no tipados
Se dice que un lenguaje tiene tipos si la especificación de
cada operación define tipos de datos para los cuales la
operación es aplicable, con la implicación de que no es
aplicable a otros tipos. Por ejemplo, “este texto entre co-
millas” es una cadena. En la mayoría de los lenguajes de
programación, dividir un número por una cadena no tiene
ningún significado. Por tanto, la mayoría de los lenguajes
de programación modernos rechazaran cualquier intento
de ejecutar dicha operación por parte de algún programa.
En algunos lenguajes, estas operaciones sin significado
son detectadas cuando el programa es compilado (valida-
ción de tipos “estática”) y son rechazadas por el compila-
dor, mientras en otros son detectadas cuando el programa
es ejecutado (validación de tipos “dinámica”) y se genera
una excepción en tiempo de ejecución.
Un caso especial de lenguajes de tipo son los lenguajes de
tipo sencillo. Estos son con frecuencia lenguajes de mar-
cado o de scripts, como REXX o SGML, y solamente
cuentan con un tipo de datos; comúnmente cadenas de
caracteres que luego son usadas tanto para datos numéri-
cos como simbólicos.
En contraste, un lenguaje sin tipos, como la mayoría de los
lenguajes ensambladores, permiten que cualquier opera-
ción se aplique a cualquier dato, que por lo general se
consideran secuencias de bits de varias longitudes. Len-
guajes de alto nivel sin datos incluyen BCPL y algunas
variedades de Forth.
En la práctica, aunque pocos lenguajes son considerados
con tipo desde el punto de vista de la teoría de tipos (es
decir, que verifican o rechazan todas las operaciones), la
mayoría de los lenguajes modernos ofrecen algún grado
de manejo de tipos. Si bien muchos lenguajes de produc-
ción proveen medios para brincarse o subvertir el sistema
de tipos.
Tipos estáticos versus tipos dinámicos
En lenguajes con tipos estáticos se determina el tipo de
todas las expresiones antes de la ejecución del programa
(típicamente al compilar). Por ejemplo, 1 y (2+2) son ex-
presiones enteras; no pueden ser pasadas a una función
que espera una cadena, ni pueden guardarse en una va-
riable que está definida como fecha.
Los lenguajes con tipos estáticos pueden manejar tipos
explícitos o tipos inferidos. En el primer caso, el progra-
mador debe escribir los tipos en determinadas posiciones
textuales. En el segundo caso, el compilador infiere los
tipos de las expresiones y las declaraciones de acuerdo al
contexto. La mayoría de los lenguajes populares con ti-
pos estáticos, tales como C++, C# y Java, manejan tipos
explícitos. Inferencia total de los tipos suele asociarse con
lenguajes menos populares, tales como Haskell y ML. Sin
embargo, muchos lenguajes de tipos explícitos permiten
inferencias parciales de tipo; tanto Java y C#, por ejem-
plo, infieren tipos en un número limitado de casos.
Los lenguajes con tipos dinámicos determinan la validez
de los tipos involucrados en las operaciones durante la
ejecución del programa. En otras palabras, los tipos están
asociados con valores en ejecución en lugar de expresiones
textuales. Como en el caso de lenguajes con tipos inferi-
dos, los lenguajes con tipos dinámicos no requieren que
el programador escriba los tipos de las expresiones. En-
tre otras cosas, esto permite que una misma variable se
pueda asociar con valores de tipos distintos en diferentes
momentos de la ejecución de un programa. Sin embargo,
los errores de tipo no pueden ser detectados automática-
mente hasta que se ejecuta el código, dificultando la de-
puración de los programas, no obstante, en lenguajes con
tipos dinámicos se suele dejar de lado la depuración en
favor de técnicas de desarrollo como por ejemplo BDD y
TDD. Ruby, Lisp, JavaScript y Python son lenguajes con
tipos dinámicos.
Tipos débiles y tipos fuertes
Los lenguajes débilmente tipados permiten que un valor
de un tipo pueda ser tratado como de otro tipo, por ejem-
plo una cadena puede ser operada como un número. Esto
puede ser útil a veces, pero también puede permitir cier-
tos tipos de fallas que no pueden ser detectadas durante
la compilación o a veces ni siquiera durante la ejecución.
Los lenguajes fuertemente tipados evitan que pase lo an-
terior. Cualquier intento de llevar a cabo una operación
sobre el tipo equivocado dispara un error. A los lenguajes
con tipos fuertes se les suele llamar de tipos seguros.
Lenguajes con tipos débiles como Perl y JavaScript per-
miten un gran número de conversiones de tipo implícitas.
Por ejemplo en JavaScript la expresión 2 * x convierte
implícitamente x a un número, y esta conversión es exi-
tosa inclusive cuando x es null, undefined, un Array o una
cadena de letras. Estas conversiones implícitas son útiles
con frecuencia, pero también pueden ocultar errores de
programación.
Las características de estáticos y fuertes son ahora ge-
neralmente consideradas conceptos ortogonales, pero su
trato en diferentes textos varia. Algunos utilizan el tér-
mino de tipos fuertes para referirse a tipos fuertemente es-
táticos o, para aumentar la confusión, simplemente como
equivalencia de tipos estáticos. De tal manera que C ha si-
do llamado tanto lenguaje de tipos fuertes como lenguaje
de tipos estáticos débiles.
19. 3.4. TÉCNICA 13
3.3 Implementación
/**
* Simple HelloButton() method.
* @version 1.0
* @author john doe <doe.j@example.com>
*/
HelloButton()
{
JButton hello = new JButton( "Hello, wor
hello.addActionListener( new HelloBtnList
// use the JFrame type until support for t
// new component is finished
JFrame frame = new JFrame( "Hello Button"
Container pane = frame.getContentPane();
pane.add( hello );
frame.pack();
frame.show(); // display the fra
}
Código fuente de un programa escrito en el lenguaje de progra-
mación Java.
La implementación de un lenguaje es la que provee una
manera de que se ejecute un programa para una deter-
minada combinación de software y hardware. Existen
básicamente dos maneras de implementar un lenguaje:
compilación e interpretación.
• Compilación: es el proceso que traduce un progra-
ma escrito en un lenguaje de programación a otro
lenguaje de programación, generando un programa
equivalente que la máquina será capaz interpretar.
Los programas traductores que pueden realizar esta
operación se llaman compiladores. Éstos, como los
programas ensambladores avanzados, pueden gene-
rar muchas líneas de código de máquina por cada
proposición del programa fuente.
• Interpretación: es una asignación de significados a
las fórmulas bien formadas de un lenguaje formal.
Como los lenguajes formales pueden definirse en
términos puramente sintácticos, sus fórmulas bien
formadas pueden no ser más que cadenas de símbo-
los sin ningún significado. Una interpretación otorga
significado a esas fórmulas.
Se puede también utilizar una alternativa para traducir
lenguajes de alto nivel. En lugar de traducir el programa
fuente y grabar en forma permanente el código objeto que
se produce durante la compilación para utilizarlo en una
ejecución futura, el programador sólo carga el programa
fuente en la computadora junto con los datos que se van
a procesar. A continuación, un programa intérprete, al-
macenado en el sistema operativo del disco, o incluido de
manera permanente dentro de la máquina, convierte cada
proposición del programa fuente en lenguaje de máquina
conforme vaya siendo necesario durante el procesamiento
de los datos. El código objeto no se graba para utilizarlo
posteriormente.
La siguiente vez que se utilice una instrucción, se la debe-
rá interpretar otra vez y traducir a lenguaje máquina. Por
ejemplo, durante el procesamiento repetitivo de los pa-
sos de un ciclo o bucle, cada instrucción del bucle tendrá
que volver a ser interpretada en cada ejecución repetida
del ciclo, lo cual hace que el programa sea más lento en
tiempo de ejecución (porque se va revisando el código
en tiempo de ejecución) pero más rápido en tiempo de
diseño (porque no se tiene que estar compilando a cada
momento el código completo). El intérprete elimina la
necesidad de realizar una compilación después de cada
modificación del programa cuando se quiere agregar fun-
ciones o corregir errores; pero es obvio que un programa
objeto compilado con antelación deberá ejecutarse con
mucha mayor rapidez que uno que se debe interpretar a
cada paso durante una ejecución del código.
La mayoría de lenguajes de alto nivel permiten la progra-
mación multipropósito, aunque muchos de ellos fueron
diseñados para permitir programación dedicada, como lo
fue el Pascal con las matemáticas en su comienzo. Tam-
bién se han implementado lenguajes educativos infantiles
como Logo mediante una serie de simples instrucciones.
En la actualidad son muy populares algunos lenguajes es-
pecialmente indicados para aplicaciones web, como Perl,
PHP, Ruby, Python o JavaScript.
3.4 Técnica
Libros sobre diversos lenguajes de programación.
Para escribir programas que proporcionen los mejores re-
sultados, cabe tener en cuenta una serie de detalles.
• Corrección. Un programa es correcto si hace lo que
debe hacer tal y como se estableció en las fases pre-
vias a su desarrollo. Para determinar si un programa
hace lo que debe, es muy importante especificar cla-
ramente qué debe hacer el programa antes de desa-
rrollarlo y, una vez acabado, compararlo con lo que
realmente hace.
• Claridad. Es muy importante que el programa sea
lo más claro y legible posible, para facilitar así su
20. 14 CAPÍTULO 3. LENGUAJE DE PROGRAMACIÓN
desarrollo y posterior mantenimiento. Al elaborar
un programa se debe intentar que su estructura sea
sencilla y coherente, así como cuidar el estilo en
la edición; de esta forma se ve facilitado el traba-
jo del programador, tanto en la fase de creación co-
mo en las fases posteriores de corrección de errores,
ampliaciones, modificaciones, etc. Fases que pue-
den ser realizadas incluso por otro programador, con
lo cual la claridad es aún más necesaria para que
otros programadores puedan continuar el trabajo fá-
cilmente. Algunos programadores llegan incluso a
utilizar Arte ASCII para delimitar secciones de có-
digo. Otros, por diversión o para impedir un análisis
cómodo a otros programadores, recurren al uso de
código ofuscado.
• Eficiencia. Se trata de que el programa, además de
realizar aquello para lo que fue creado (es decir, que
sea correcto), lo haga gestionando de la mejor for-
ma posible los recursos que utiliza. Normalmente, al
hablar de eficiencia de un programa, se suele hacer
referencia al tiempo que tarda en realizar la tarea pa-
ra la que ha sido creado y a la cantidad de memoria
que necesita, pero hay otros recursos que también
pueden ser de consideración al obtener la eficiencia
de un programa, dependiendo de su naturaleza (es-
pacio en disco que utiliza, tráfico de red que genera,
etc.).
• Portabilidad. Un programa es portable cuando tiene
la capacidad de poder ejecutarse en una plataforma,
ya sea hardware o software, diferente a aquella en la
que se elaboró. La portabilidad es una característi-
ca muy deseable para un programa, ya que permite,
por ejemplo, a un programa que se ha desarrollado
para sistemas GNU/Linux ejecutarse también en la
familia de sistemas operativos Windows. Esto per-
mite que el programa pueda llegar a más usuarios
más fácilmente.
3.4.1 Paradigmas
Los programas se pueden clasificar por el paradigma del
lenguaje que se use para producirlos. Los principales pa-
radigmas son: imperativos, declarativos y orientación a
objetos.
Los programas que usan un lenguaje imperativo espe-
cifican un algoritmo, usan declaraciones, expresiones y
sentencias.[3]
Una declaración asocia un nombre de va-
riable con un tipo de dato, por ejemplo: var x: integer;.
Una expresión contiene un valor, por ejemplo: 2 + 2 con-
tiene el valor 4. Finalmente, una sentencia debe asignar
una expresión a una variable o usar el valor de una varia-
ble para alterar el flujo de un programa, por ejemplo: x
:= 2 + 2; if x == 4 then haz_algo();. Una crítica común
en los lenguajes imperativos es el efecto de las sentencias
de asignación sobre una clase de variables llamadas “no
locales”.[4]
Los programas que usan un lenguaje declarativo especifi-
can las propiedades que la salida debe conocer y no espe-
cifica cualquier detalle de implementación. Dos amplias
categorías de lenguajes declarativos son los lenguajes
funcionales y los lenguajes lógicos. Los lenguajes funcio-
nales no permiten asignaciones de variables no locales,
así, se hacen más fácil, por ejemplo, programas como fun-
ciones matemáticas.[4]
El principio detrás de los lengua-
jes lógicos es definir el problema que se quiere resolver (el
objetivo) y dejar los detalles de la solución al sistema.[5]
El objetivo es definido dando una lista de sub-objetivos.
Cada sub-objetivo también se define dando una lista de
sus sub-objetivos, etc. Si al tratar de buscar una solución,
una ruta de sub-objetivos falla, entonces tal sub-objetivo
se descarta y sistemáticamente se prueba otra ruta.
La forma en la cual se programa puede ser por medio
de texto o de forma visual. En la programación visual los
elementos son manipulados gráficamente en vez de espe-
cificarse por medio de texto.
3.5 Véase también
• Anexo:Lenguajes de programación
• Programación estructurada
• Programación modular
• Programación orientada a objetos
• Programación imperativa
• Programación declarativa
• paradigma de programación
• Lenguajes esotéricos
3.6 Referencias
[1] Lutz, Mark (2010). O'Reilly Media, Inc., ed. «Learning
Python, Fourth Edition» (libro). O'Reilly. Consultado el
11 de febrero de 2010.
[2] http://www.softwarepreservation.org/projects/
FORTRAN/index.html#By_FORTRAN_project_
members
[3] Wilson, Leslie B. (1993). Comparative Programming Lan-
guages, Second Edition. Addison-Wesley. p. 75. ISBN 0-
201-56885-3. (en inglés).
[4] Wilson, Leslie B. (1993). Comparative Programming Lan-
guages, Second Edition. Addison-Wesley. p. 213. ISBN 0-
201-56885-3. (en inglés).
[5] Wilson, Leslie B. (1993). Comparative Programming Lan-
guages, Second Edition. Addison-Wesley. p. 244. ISBN 0-
201-56885-3. (en inglés).
21. 3.7. ENLACES EXTERNOS 15
3.7 Enlaces externos
• Wikimedia Commons alberga contenido
multimedia sobre Lenguaje de programación.
Commons
• Wikiversidad alberga proyectos de aprendizaje
sobre Lenguaje de programación.Wikiversidad
Wikilibros
• Wikilibros alberga un libro o manual sobre
Fundamentos de programación.
• Árbol genealógico de los lenguajes de programación
(en inglés)
• Lista de lenguajes de programación (en inglés)
• Lenguajes clasificados por paradigmas de progra-
mación: definiciones, ventajas y desventajas.
22. Capítulo 4
Algoritmo
La lámpara
no funciona
¿Está
enchufada?
¿Foco
quemado?
Comprar
nueva lámpara
No
Reemplazar
el foco
Enchufarla
Sí
No
Sí
Los diagramas de flujo sirven para representar algoritmos de
manera gráfica.
En matemáticas, lógica, ciencias de la computación y dis-
ciplinas relacionadas, un algoritmo (del griego y latín,
dixit algorithmus y este a su vez del matemático persa Al-
Juarismi[1]
) es un conjunto prescrito de instrucciones o
reglas bien definidas, ordenadas y finitas que permite rea-
lizar una actividad mediante pasos sucesivos que no gene-
ren dudas a quien deba realizar dicha actividad.[2]
Dados
un estado inicial y una entrada, siguiendo los pasos sucesi-
vos se llega a un estado final y se obtiene una solución. Los
algoritmos son el objeto de estudio de la algoritmia.[1]
En la vida cotidiana, se emplean algoritmos frecuente-
mente para resolver problemas. Algunos ejemplos son los
manuales de usuario, que muestran algoritmos para usar
un aparato, o las instrucciones que recibe un trabajador
por parte de su patrón. Algunos ejemplos en matemática
son el algoritmo de multiplicación, para calcular el pro-
ducto, el algoritmo de la división para calcular el cocien-
te de dos números, el algoritmo de Euclides para obtener
el máximo común divisor de dos enteros positivos, o el
método de Gauss para resolver un sistema lineal de ecua-
ciones.
4.1 Definición formal
En general, no existe ningún consenso definitivo en cuan-
to a la definición formal de algoritmo. Muchos autores
los señalan como listas de instrucciones para resolver un
cálculo o un problema abstracto, es decir, que un número
finito de pasos convierten los datos de un problema (en-
trada) en una solución (salida).[1][2][3][4][5][6]
Sin embar-
go cabe notar que algunos algoritmos no necesariamente
tienen que terminar o resolver un problema en particular.
Por ejemplo, una versión modificada de la criba de Era-
tóstenes que nunca termine de calcular números primos
no deja de ser un algoritmo.[7]
A lo largo de la historia varios autores han tratado de
definir formalmente a los algoritmos utilizando modelos
matemáticos. Esto fue realizado por Alonzo Church en
1936 con el concepto de “calculabilidad efectiva” basa-
da en su cálculo lambda y por Alan Turing basándose en
la máquina de Turing. Los dos enfoques son equivalen-
tes, en el sentido en que se pueden resolver exactamente
los mismos problemas con ambos enfoques.[8][9]
Sin em-
bargo, estos modelos están sujetos a un tipo particular de
datos como son números, símbolos o gráficas mientras
que, en general, los algoritmos funcionan sobre una vasta
cantidad de estructuras de datos.[3][1]
En general, la parte
común en todas las definiciones se puede resumir en las
siguientes tres propiedades siempre y cuando no conside-
remos algoritmos paralelos:[7]
Tiempo secuencial. Un algoritmo funciona en
tiempo discretizado –paso a paso–, definiendo
así una secuencia de estados "computacionales"
por cada entrada válida (la entrada son los da-
tos que se le suministran al algoritmo antes de
comenzar).
Estado abstracto. Cada estado computacional
puede ser descrito formalmente utilizando una
estructura de primer orden y cada algoritmo es
16
23. 4.2. MEDIOS DE EXPRESIÓN DE UN ALGORITMO 17
independiente de su implementación (los algo-
ritmos son objetos abstractos) de manera que
en un algoritmo las estructuras de primer orden
son invariantes bajo isomorfismo.
Exploración acotada. La transición de un es-
tado al siguiente queda completamente deter-
minada por una descripción fija y finita; es de-
cir, entre cada estado y el siguiente solamente
se puede tomar en cuenta una cantidad fija y
limitada de términos del estado actual.
En resumen, un algoritmo es cualquier cosa que funcio-
ne paso a paso, donde cada paso se pueda describir sin
ambigüedad y sin hacer referencia a una computadora en
particular, y además tiene un límite fijo en cuanto a la
cantidad de datos que se pueden leer/escribir en un so-
lo paso. Esta amplia definición abarca tanto a algoritmos
prácticos como aquellos que solo funcionan en teoría, por
ejemplo el método de Newton y la eliminación de Gauss-
Jordan funcionan, al menos en principio, con números de
precisión infinita; sin embargo no es posible programar la
precisión infinita en una computadora, y no por ello dejan
de ser algoritmos.[10]
En particular es posible considerar
una cuarta propiedad que puede ser usada para validar la
tesis de Church-Turing de que toda función calculable se
puede programar en una máquina de Turing (o equivalen-
temente, en un lenguaje de programación suficientemente
general):[10]
Aritmetizabilidad. Solamente operaciones
innegablemente calculables están disponibles
en el paso inicial.
4.2 Medios de expresión de un al-
goritmo
Los algoritmos pueden ser expresados de muchas ma-
neras, incluyendo al lenguaje natural, pseudocódigo,
diagramas de flujo y lenguajes de programación entre
otros. Las descripciones en lenguaje natural tienden a ser
ambiguas y extensas. El usar pseudocódigo y diagramas
de flujo evita muchas ambigüedades del lenguaje natural.
Dichas expresiones son formas más estructuradas para re-
presentar algoritmos; no obstante, se mantienen indepen-
dientes de un lenguaje de programación específico.
La descripción de un algoritmo usualmente se hace en tres
niveles:
1. Descripción de alto nivel. Se establece el proble-
ma, se selecciona un modelo matemático y se expli-
ca el algoritmo de manera verbal, posiblemente con
ilustraciones y omitiendo detalles.
2. Descripción formal. Se usa pseudocódigo para des-
cribir la secuencia de pasos que encuentran la solu-
ción.
3. Implementación. Se muestra el algoritmo expresa-
do en un lenguaje de programación específico o al-
gún objeto capaz de llevar a cabo instrucciones.
También es posible incluir un teorema que demuestre que
el algoritmo es correcto, un análisis de complejidad o am-
bos.
4.2.1 Diagrama de flujo
Diagrama de flujo que expresa un algoritmo para calcular la raíz
cuadrada de un número x
Los diagramas de flujo son descripciones gráficas de algo-
ritmos; usan símbolos conectados con flechas para indicar
la secuencia de instrucciones y están regidos por ISO.
Los diagramas de flujo son usados para representar al-
goritmos pequeños, ya que abarcan mucho espacio y su
construcción es laboriosa. Por su facilidad de lectura son
usados como introducción a los algoritmos, descripción
de un lenguaje y descripción de procesos a personas aje-
nas a la computación.
4.2.2 Pseudocódigo
El pseudocódigo (falso lenguaje, el prefijo pseudo signifi-
ca falso) es una descripción de alto nivel de un algoritmo
que emplea una mezcla de lenguaje natural con algunas
convenciones sintácticas propias de lenguajes de progra-
mación, como asignaciones, ciclos y condicionales, aun-
24. 18 CAPÍTULO 4. ALGORITMO
que no está regido por ningún estándar. Es utilizado para
describir algoritmos en libros y publicaciones científicas,
y como producto intermedio durante el desarrollo de un
algoritmo, como los diagramas de flujo, aunque presentan
una ventaja importante sobre estos, y es que los algorit-
mos descritos en pseudocódigo requieren menos espacio
para representar instrucciones complejas.
El pseudocódigo está pensado para facilitar a las perso-
nas el entendimiento de un algoritmo, y por lo tanto pue-
de omitir detalles irrelevantes que son necesarios en una
implementación. Programadores diferentes suelen utili-
zar convenciones distintas, que pueden estar basadas en la
sintaxis de lenguajes de programación concretos. Sin em-
bargo, el pseudocódigo, en general, es comprensible sin
necesidad de conocer o utilizar un entorno de programa-
ción específico, y es a la vez suficientemente estructurado
para que su implementación se pueda hacer directamente
a partir de él.
Así el pseudocódigo cumple con las funciones antes men-
cionadas para representar algo abstracto los protocolos
son los lenguajes para la programación. Busque fuentes
más precisas para tener mayor comprensión del tema.
4.2.3 Sistemas formales
La teoría de autómatas y la teoría de funciones recur-
sivas proveen modelos matemáticos que formalizan el
concepto de algoritmo. Los modelos más comunes son
la máquina de Turing, máquina de registro y funciones
μ-recursivas. Estos modelos son tan precisos como un
lenguaje máquina, careciendo de expresiones coloquiales
o ambigüedad, sin embargo se mantienen independien-
tes de cualquier computadora y de cualquier implemen-
tación.
4.2.4 Implementación
Muchos algoritmos son ideados para implementarse en
un programa. Sin embargo, los algoritmos pueden ser im-
plementados en otros medios, como una red neuronal, un
circuito eléctrico o un aparato mecánico y eléctrico. Al-
gunos algoritmos inclusive se diseñan especialmente para
implementarse usando lápiz y papel. El algoritmo de mul-
tiplicación tradicional, el algoritmo de Euclides, la criba
de Eratóstenes y muchas formas de resolver la raíz cua-
drada son sólo algunos ejemplos.
4.2.5 Variables
Son elementos que toman valores específicos de un tipo
de datos concreto. La declaración de una variable puede
realizarse comenzando con var. Principalmente, existen
dos maneras de otorgar valores iniciales a variables:
1. Mediante una sentencia de asignación.
2. Mediante un procedimiento de entrada de datos (por
ejemplo: 'read').
Ejemplo:
... i:=1; read(n); while i < n do begin (* cuerpo del bucle
*) i := i + 1 end; ...
4.2.6 Estructuras secuenciales
La estructura secuencial es aquella en la que una acción
sigue a otra en secuencia. Las operaciones se suceden de
tal modo que la salida de una es la entrada de la siguiente
y así sucesivamente hasta el fin del proceso. La asignación
de esto consiste, en el paso de valores o resultados a una
zona de la memoria. Dicha zona será reconocida con el
nombre de la variable que recibe el valor. La asignación
se puede clasificar de la siguiente forma:
1. Simples: Consiste en pasar un valor constante a una
variable (a ← 15)
2. Contador: Consiste en usarla como un verificador
del número de veces que se realiza un proceso (a ←
a + 1)
3. Acumulador: Consiste en usarla como un sumador
en un proceso (a ← a + b)
4. De trabajo: Donde puede recibir el resultado de una
operación matemática que involucre muchas varia-
bles (a ← c + b*2/4).
Un ejemplo de estructura secuencial, como obtener la
área de un triángulo:
Inicio ... float b, h, a; printf(“Diga la base”); scanf("%f”,
&b); printf(“Diga la altura”); scanf("%f”, &h); a =
(b*h)/2; printf(“El área del triángulo es %f”, a) ... Fin
4.3 Algoritmos como funciones
Esquemática de un algoritmo solucionando un problema de ciclo
hamiltoniano.
Un algoritmo se puede concebir como una función que
transforma los datos de un problema (entrada) en los da-
tos de una solución (salida). Más aun, los datos se pueden
representar a su vez como secuencias de bits, y en general,
de símbolos cualesquiera.[1][9][11]
Como cada secuencia
de bits representa a un número natural (véase Sistema bi-
nario), entonces los algoritmos son en esencia funciones
de los números naturales en los números naturales que sí
se pueden calcular. Es decir que todo algoritmo calcula
25. 4.5. EJEMPLO DE ALGORITMO 19
una función f : N → N donde cada número natural es la
codificación de un problema o de una solución.
En ocasiones los algoritmos son susceptibles de nunca ter-
minar, por ejemplo, cuando entran a un bucle infinito.
Cuando esto ocurre, el algoritmo nunca devuelve ningún
valor de salida, y podemos decir que la función queda
indefinida para ese valor de entrada. Por esta razón se
considera que los algoritmos son funciones parciales, es
decir, no necesariamente definidas en todo su dominio de
definición.
Cuando una función puede ser calculada por medios algo-
rítmicos, sin importar la cantidad de memoria que ocu-
pe o el tiempo que se tarde, se dice que dicha función
es computable. No todas las funciones entre secuencias
datos son computables. El problema de la parada es un
ejemplo.
4.4 Análisis de algoritmos
Como medida de la eficiencia de un algoritmo, se suelen
estudiar los recursos (memoria y tiempo) que consume
el algoritmo. El análisis de algoritmos se ha desarrollado
para obtener valores que de alguna forma indiquen (o es-
pecifiquen) la evolución del gasto de tiempo y memoria
en función del tamaño de los valores de entrada.
El análisis y estudio de los algoritmos es una disciplina de
las ciencias de la computación y, en la mayoría de los ca-
sos, su estudio es completamente abstracto sin usar nin-
gún tipo de lenguaje de programación ni cualquier otra
implementación; por eso, en ese sentido, comparte las ca-
racterísticas de las disciplinas matemáticas. Así, el aná-
lisis de los algoritmos se centra en los principios básicos
del algoritmo, no en los de la implementación particular.
Una forma de plasmar (o algunas veces “codificar”) un
algoritmo es escribirlo en pseudocódigo o utilizar un len-
guaje muy simple tal como Lexico, cuyos códigos pueden
estar en el idioma del programador.
Algunos escritores restringen la definición de algoritmo
a procedimientos que deben acabar en algún momento,
mientras que otros consideran procedimientos que po-
drían ejecutarse eternamente sin pararse, suponiendo el
caso en el que existiera algún dispositivo físico que fue-
ra capaz de funcionar eternamente. En este último caso,
la finalización con éxito del algoritmo no se podría defi-
nir como la terminación de este con una salida satisfac-
toria, sino que el éxito estaría definido en función de las
secuencias de salidas dadas durante un periodo de vida
de la ejecución del algoritmo. Por ejemplo, un algoritmo
que verifica que hay más ceros que unos en una secuencia
binaria infinita debe ejecutarse siempre para que pueda
devolver un valor útil. Si se implementa correctamente,
el valor devuelto por el algoritmo será válido, hasta que
evalúe el siguiente dígito binario. De esta forma, mien-
tras evalúa la siguiente secuencia podrán leerse dos tipos
de señales: una señal positiva (en el caso de que el nú-
mero de ceros sea mayor que el de unos) y una negativa
en caso contrario. Finalmente, la salida de este algoritmo
se define como la devolución de valores exclusivamente
positivos si hay más ceros que unos en la secuencia y, en
cualquier otro caso, devolverá una mezcla de señales po-
sitivas y negativas.
4.5 Ejemplo de algoritmo
El problema consiste en encontrar el máximo de un con-
junto de números. Para un ejemplo más complejo véase
Algoritmo de Euclides.
4.5.1 Descripción de alto nivel
Dado un conjunto finito C de números, se tiene el pro-
blema de encontrar el número más grande. Sin pérdi-
da de generalidad se puede asumir que dicho conjunto
no es vacío y que sus elementos están numerados como
c0, c1, . . . , cn .
Es decir, dado un conjunto C = {c0, c1, . . . , cn} se pide
encontrar m tal que x ≤ m para todo elemento x que
pertenece al conjunto C .
Para encontrar el elemento máximo, se asume que el pri-
mer elemento ( c0 ) es el máximo; luego, se recorre el
conjunto y se compara cada valor con el valor del má-
ximo número encontrado hasta ese momento. En el caso
que un elemento sea mayor que el máximo, se asigna su
valor al máximo. Cuando se termina de recorrer la lista,
el máximo número que se ha encontrado es el máximo de
todo el conjunto.
4.5.2 Descripción formal
El algoritmo puede ser escrito de una manera más formal
en el siguiente pseudocódigo:
Sobre la notación:
• "←" representa una asignación: m ← x significa que
la variable m toma el valor de x ;
• "devolver" termina el algoritmo y devuelve el valor
a su derecha (en este caso, el máximo de C ).
4.5.3 Implementación
En lenguaje C++:
int max(int c[], int n) { int i, m = c[0]; for (i = 1; i < n;
i++) if (c[i] > m) m = c[i]; return m; }
26. 20 CAPÍTULO 4. ALGORITMO
4.6 Véase también
4.6.1 Tipos de algoritmos según su función
• Algoritmo de ordenamiento
• Algoritmo de búsqueda
4.6.2 Técnicas de diseño de algoritmos
• Algoritmos voraces (greedy): seleccionan los ele-
mentos más prometedores del conjunto de candida-
tos hasta encontrar una solución. En la mayoría de
los casos la solución no es óptima.
• Algoritmos paralelos: permiten la división de un
problema en subproblemas de forma que se puedan
ejecutar de forma simultánea en varios procesado-
res.
• Algoritmos probabilísticos: algunos de los pasos de
este tipo de algoritmos están en función de valores
pseudoaleatorios.
• Algoritmos determinísticos: el comportamiento del
algoritmo es lineal: cada paso del algoritmo tiene
únicamente un paso sucesor y otro antecesor.
• Algoritmos no determinísticos: el comportamiento
del algoritmo tiene forma de árbol y a cada paso del
algoritmo puede bifurcarse a cualquier número de
pasos inmediatamente posteriores, además todas las
ramas se ejecutan simultáneamente.
• Divide y vencerás: dividen el problema en subcon-
juntos disjuntos obteniendo una solución de cada
uno de ellos para después unirlas, logrando así la so-
lución al problema completo.
• Metaheurísticas: encuentran soluciones aproxima-
das (no óptimas) a problemas basándose en un cono-
cimiento anterior (a veces llamado experiencia) de
los mismos.
• Programación dinámica: intenta resolver problemas
disminuyendo su coste computacional aumentando
el coste espacial.
• Ramificación y acotación: se basa en la construcción
de las soluciones al problema mediante un árbol im-
plícito que se recorre de forma controlada encon-
trando las mejores soluciones.
• Vuelta atrás (backtracking): se construye el espa-
cio de soluciones del problema en un árbol que se
examina completamente, almacenando las solucio-
nes menos costosas.
4.6.3 Temas relacionados
• Cota inferior asintótica
• Cota ajustada asintótica
• Complejidad computacional
• Diagramas de flujo
• Diagrama Nassi-Shneiderman
• Máquina de Turing
4.6.4 Disciplinas relacionadas
• Ciencias de la Computación
• Análisis de algoritmos
• Complejidad computacional
• Informática
• Inteligencia artificial
• Investigación operativa
• Matemáticas
• Programación
4.7 Referencias
[1] Brassard, Gilles; Bratley, Paul (1997). Fundamentos
de Algoritmia. Madrid: PRENTICE HALL. ISBN 84-
89660-00-X.
[2] Real Academia Española. Diccionario de la lengua espa-
ñola "Conjunto ordenado y finito de operaciones que per-
mite hallar la solución de un problema."
[3] Cormen, Thomas; Leiserson, Charles; Rivest, Ronald;
Stein, Clifford (2009). Introduction to algorithms. Cam-
bridge, Massachusetts: The MIT Press. ISBN 978-0-262-
53305-8.
[4] Ralph P. Grimaldi (1998). «Propiedades de los números
enteros: Inducción matemática». Matemáticas Discreta y
Combinatoria. México: Addison Wesley Longman de Mé-
xico. ISBN 968-444-324-2.
[5] Johnsonbaugh, Richard (2005). «Introducción a la teoría
de números». Matemáticas Discretas. México: PEARSON
EDUCACIÓN. ISBN 970-26-0637-3.
[6] Carl Reynolds & Paul Tymann (2008). Schaum’s Outli-
ne of Principles of Computer Science. McGraw-Hill. ISBN
978-0-07-146051-4.
[7] Gurevich, Yuri (2000). «Sequential Abstract State Machi-
nes capture Sequential Algorithms». ACM Transactions
on Computational Logic 1 (1). ISSN 1529-3785, 77-111.
27. 4.9. ENLACES EXTERNOS 21
[8] John E. Savage (1987). The Complexity of Computing.
Krieger Publishing Co. ISBN 089874833X.
[9] Sipser, Michael (2005). Introduction to the Theory of
Computation (2 edición). Course Technology. ISBN 978-
0534950972.
[10] Nachum Dershowitz & Yuri Gurevich (2008). «A na-
tural axiomatization of computability and proof of
Church’s Thesis». Bulletin of Symbolic Logic 14 (3). ISSN
10798986, 299-350.
[11] Kelley, Dean (1995). Teoría de Autómatas y Lenguajes
Formales. Prentice Hall. ISBN 0-13-497777-7.
4.8 Bibliografía
• Aho, A. The Design and Analysis of Computer Algo-
rithms
• Cormen, T. H., Leiserson, C. E., Rivest, R. L. y
Stein, C. Introduction to Algorithms (2nd ed.)
• Brassard, G. y P. Bratley. Fundamentos de Algorit-
mia, (ISBN 848966000X)
• Knuth, D. E. The Art of Computer Programming,
[quien fue también, el creador del TeX]
• Mamber, U. Introduction to Algorithms. A Creative
Approach
• Sedgewick, R. Algorithms in C (3r ed) (también exis-
ten versiones en C++ y Java)
4.9 Enlaces externos
Wikilibros
• Wikilibros alberga un libro o manual sobre
Algoritmia.
• Wikcionario tiene definiciones y otra informa-
ción sobre algoritmo.Wikcionario
• Portal de algoritmia
• Técnicas de Diseño de Algoritmos manual que ex-
plica y ejemplifica los distintos paradigmas de dise-
ño de algoritmos. Rosa Guerequeta y Antonio Va-
llecillo (profesores de la Universidad de Málaga).
• Transparencias de la asignatura “Esquemas Algorít-
micos”, Campos, J.
• Apuntes y problemas de Algorítmica por Domingo
Giménez Cánovas
• Curso de Diseño de Algoritmos de Carlos Pes
28. Capítulo 5
Algoritmo determinista
En ciencias de la computación, un algoritmo determi-
nista es un algoritmo que, en términos informales, es
completamente predictivo si se conocen sus entradas. Di-
cho de otra forma, si se conocen las entradas del algoritmo
siempre producirá la misma salida, y la máquina interna
pasará por la misma secuencia de estados. Este tipo de
algoritmos ha sido el más estudiado durante la historia y
por lo tanto resulta ser el tipo más familiar de los algorit-
mos, así como el más práctico ya que puede ejecutarse en
las máquinas eficientemente.
Un modelo simple de algoritmo determinista es la función
matemática, pues esta extrae siempre la misma salida pa-
ra una entrada dada. No obstante un algoritmo describe
explícitamente cómo la salida se obtiene de la entrada,
mientras que las funciones definen implícitamente su sa-
lida.
5.1 Definición formal
Formalmente los algoritmos deterministas se pueden de-
finir en términos de una máquina de estado; un «estado»
describe qué está haciendo la máquina en un instante par-
ticular de tiempo. Justo cuando se produce la entrada,
la máquina comienza en su «estado inicial» y, posterior-
mente, si la máquina es determinista, comenzará la eje-
cución de la secuencia de estados predeterminados. Una
máquina puede ser determinista y no tener límite tempo-
ral para la ejecución o quedarse en un bucle de estados
cíclicos eternamente.
Ejemplos de máquinas abstractas deterministas son las
máquinas de Turing deterministas y los autómatas finitos
deterministas.
5.2 Cuándo un algoritmo puede
volverse no determinista
Por diversos motivos un algoritmo determinista puede
comportarse de una forma no determinista:
• Si emplea en la ejecución de la secuencia de estados
otro estado «externo» como entrada del proceso; por
ejemplo: una entrada de un usuario, una variable ob-
jetivo, un valor de un temporizador de hardware, un
valor aleatorio, etc.
• Si al operar se encuentra con concurrencia de es-
tados; por ejemplo, si tiene múltiples procesadores
escribiendo al mismo tiempo en un fichero. En es-
te caso el orden preciso en el que cada procesador
escribe el dato puede afectar a la salida.
• Si un error (cuyo origen puede deberse al hardware
o al software) causa un inesperado cambio en la se-
cuencia de ejecución de estados.
Aunque los programas reales rara vez son puramente de-
terministas, es conveniente considerar que sí lo son ya
que es más fácil razonar sobre estos. Por este motivo,
la mayoría de los lenguajes de programación y especial-
mente aquellos que entran dentro de la categoría de la
programación funcional son lenguajes que hacen un es-
fuerzo en prevenir eventos que se ejecuten sin control.
Este tipo de restricciones fuerzan el carácter determinis-
ta y por ello a los algoritmos deterministas se les suele
denominar puramente funcionales.
La prevalencia de los procesadores de varios núcleos ha
levantado el interés por el determinismo en la programa-
ción en paralelo y se han documentado bien los problemas
del no determinismo.[1][2]
Numerosas herramientas útiles
en estos problemas se han propuesto para tratar con los
bloqueos mutuos y las condiciones de carrera.[3][4][5][6][7]
5.3 Problemas con los algoritmos
deterministas
Para algunos problemas es muy difícil implementar un
algoritmo determinista. Por ejemplo, existen eficientes y
simples algoritmos probabilistas que pueden determinar
si un número entero es primo o no, pero tienen una pe-
queña posibilidad de equivocarse. Algunos de ellos son
muy conocidos desde los 1970 (véase, por ejemplo, el test
de primalidad de Fermat); sin embargo tuvieron que pa-
sar 30 años para que se desarrollara un algoritmo deter-
minista similar que fuera asintóticamente igual de rápido
(véase AKS).[8]
22
29. 5.5. VÉASE TAMBIÉN 23
Otro ejemplo puede encontrarse en los problemas NP-
completos. Dentro de esta categoría puede encontrarse la
mayoría de los problemas prácticos; este tipo de proble-
mas puede resolverse rápidamente empleando de forma
masiva y paralela una máquina de Turing no determinista,
pero no se ha encontrado aún un algoritmo eficiente pa-
ra esta tarea, tan solo soluciones aproximadas para casos
especiales.
Otro problema sobre el planteamiento de algoritmos de-
terministas es que a veces no es «deseable» que los resul-
tados sean completamente predecibles. Por ejemplo, en
un juego on-line de blackjack que utiliza un generador
pseudoaleatorio de números para barajar las cartas, un
jugador astuto podría determinar con exactitud los nú-
meros que el generador fuera a elegir y por consiguiente
averiguar el contenido del mazo antes de tiempo. Proble-
mas similares pueden encontrarse en criptografía, donde
las claves privadas a menudo se crean mediante uno de es-
tos generadores. Este tipo de problemas se evita mediante
el empleo de un generador de números pseudo-aleatorios
criptográficamente seguro.
5.4 Notas al pie
[1] Edward A. Lee. «The Problem with Threads». Consultado
el 29-5-2009.
[2] James Reinders. «Parallel terminology definitions». Con-
sultado el 29-5-2009.
[3] «Intel Parallel Inspector Thread Checker». Consultado el
29-5-2009.
[4] Yuan Lin. «Data Race and Deadlock Detection with Sun
Studio Thread Analyzer». Consultado el 29-5-2009.
[5] Intel. «Intel Parallel Inspector». Consultado el 29-5-2009.
[6] David Worthington. «Intel addresses development life cy-
cle with Parallel Studio». Consultado el 26-5-2009.
[7] Véase el Intel Parallel Studio.
[8] Manindra Agrawal, Neeraj Kayal, Nitin Saxena (2004).
«PRIMES is in P». Annals of Mathematics 160 (2). ISSN
0003-486X , 781-793.
5.5 Véase también
• Algoritmo no determinista
30. Capítulo 6
Estructura de datos
En programación, una estructura de datos es una forma
particular de organizar datos en una computadora para
que pueda ser utilizado de manera eficiente.
Diferentes tipos de estructuras de datos son adecuadas
para diferentes tipos de aplicaciones, y algunos son alta-
mente especializados para tareas específicas.
Las estructuras de datos son un medio para manejar gran-
des cantidades de datos de manera eficiente para usos ta-
les como grandes bases de datos y servicios de indización
de internet. Por lo general, las estructuras de datos eficien-
tes son clave para diseñar eficientes algoritmos. Algunos
métodos formales de diseño y lenguajes de programación
destacan las estructuras de datos, en lugar de los algorit-
mos, como el factor clave de organización en el diseño de
software.
6.1 Descripción
Las estructuras de datos se basan generalmente en la ca-
pacidad de un ordenador para recuperar y almacenar da-
tos en cualquier lugar de su memoria.
6.2 Estructuras de datos en pro-
gramación
En Programación una estructura de datos puede ser de-
clarada inicialmente escribiendo una palabra reservada,
luego un identificador para la estructura y un nombre para
cada uno de sus miembros, sin olvidar los tipos de datos
que estos representan. Generalmente, cada miembro va
separado por algún tipo de operador, caracter o palabra
reservada.
En el lenguaje de programación Pauscal es posible crear
una estructura de datos de la forma recién mencionada.
La sintaxis basica es:
Estruc Identificador, _ Miembro1:TipoDeDato, _
Miembro2:TipoDeDato, _ ... Miembro9:TipoDeDato
Para acceder a los miembros de una estructura primero
se debe crear una referencia a esta, generalmente con una
variable de tipo, luego se pueden editar y obtener los datos
de los miembros libremente.
Estruc Estructura,Miembro1:Entero,Miembro2:
Cadena,Miembro3:Byte Var Variable:Estructura
Variable.Miembro1 = 40000 Variable.Miembro2 =
“Hola Mundo” Variable.Miembro3 = 255 Mensa-
je(Variable.Miembro2) ' Muestra “Hola Mundo”
6.3 Véase también
• Unión de datos
• Lenguaje de programación
• Tipo de dato
• Algoritmo
24
31. Capítulo 7
Cola (informática)
Desencolar
Encolar
Final Principio
Representación simplificada de una cola
7.1 Usos concretos de la cola
La particularidad de una estructura de datos de cola es el
hecho de que sólo podemos acceder al primer y al últi-
mo elemento de la estructura. Así mismo, los elementos
sólo se pueden eliminar por el principio y sólo se pueden
añadir por el final de la cola.
Ejemplo de Cola
Ejemplos de colas en la vida real serían: personas com-
prando en un supermercado, esperando para entrar a ver
un partido de fútbol, esperando en el cine para ver una
película, una pequeña peluquería, etc. La idea esencial es
que son todos líneas de espera.
7.2 Información adicional
En caso de estar vacía, borrar un elemento sería imposi-
ble hasta que no se añade un nuevo elemento. A la hora
de añadir un elemento podríamos darle una mayor im-
portancia a unos elementos que a otros (un cargo VIP) y
para ello se crea un tipo de cola especial que es la cola de
prioridad. (Ver cola de prioridad).
7.3 Operaciones Básicas
• Crear: se crea la cola vacía.
• Encolar: (añadir, entrar, insertar): se añade un ele-
mento a la cola. Se añade al final de esta.
• Desencolar: (sacar, salir, eliminar): se elimina el
elemento frontal de la cola, es decir, el primer ele-
mento que entró.
• Frente: (consultar, front): se devuelve el elemento
frontal de la cola, es decir, el primer elemento que
entró.
7.4 Implementaciones
7.4.1 Colas en Pascal
Clase PscColas, Matriz[]:Cadena, Posición, Va-
lor:Entero Privado: Proc Comenzar ReDim Matriz,1
Posición = 0 Valor = 0 FinProc Proc Terminar Borrar
Matriz FinProc Proc Longitud:Entero Devolver
Límite(Matriz) FinProc Proc ReDimencionarLaCola
ReDim Preservar Matriz, LongMat(Matriz) + 1
FinProc Público: Proc Encolar(Contenido:Cadena)
Si Posición = LongMat(Matriz) Entonces ReDi-
mencionarLaCola Matriz[Posición] = Contenido
Posición = Posición + 1 FinProc Proc DesEncolar
Si Neg(Valor >= Límite(Matriz)) Entonces Valor =
Valor + 1 FinProc Proc FrenteCola:Cadena Devol-
ver Matriz[Valor] FinProc Proc FondoCola:Cadena
Devolver Matriz[Límite(Matriz)] FinProc Prop
25