See	discussions,	stats,	and	author	profiles	for	this	publication	at:	https://www.researchgate.net/publication/280035971
Algoritmos	y	Estructura	de	Datos,	Parte	1	de	7:
Introducción	y	conceptos	básicos
Book	·	July	2015
DOI:	10.13140/RG.2.1.4120.4321
CITATIONS
0
READS
372
5	authors,	including:
Some	of	the	authors	of	this	publication	are	also	working	on	these	related	projects:
active	with	my	students	in	Hacking	Lab:	www.hacking-lab.com	View	project
Wikipedia	Books	-	free,	downloadable,	multilingual	lecture	notes	View	project
Reiner	Creutzburg
Brandenburg	University	of	Applied	Sciences
459	PUBLICATIONS			332	CITATIONS			
SEE	PROFILE
All	content	following	this	page	was	uploaded	by	Reiner	Creutzburg	on	14	July	2015.
The	user	has	requested	enhancement	of	the	downloaded	file.
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	
  
Índice general
1 Computadora 1
1.1 Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Unidad central de procesamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.2 Memoria primaria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.3 Periféricos de Entrada, de Salida o de Entrada/Salida . . . . . . . . . . . . . . . . . . . . 3
1.1.4 Buses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Otros conceptos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Etimología de la palabra ordenador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.2 Tipos de computadoras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.3 Componentes y periféricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.4 Otros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 Ciencias de la información (tecnología) 7
3 Lenguaje de programación 8
3.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2 Elementos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.1 Variables y vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.2 Condicionantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.3 Bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.4 Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.5 Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.6 Semántica estática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2.7 Sistema de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4 Técnica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.1 Paradigmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
i
ii ÍNDICE GENERAL
3.7 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4 Algoritmo 16
4.1 Definición formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.2 Medios de expresión de un algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2.1 Diagrama de flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2.2 Pseudocódigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2.3 Sistemas formales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2.4 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2.5 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2.6 Estructuras secuenciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.3 Algoritmos como funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.4 Análisis de algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.5 Ejemplo de algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.5.1 Descripción de alto nivel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.5.2 Descripción formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.5.3 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.6 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.6.1 Tipos de algoritmos según su función . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.6.2 Técnicas de diseño de algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.6.3 Temas relacionados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.6.4 Disciplinas relacionadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.7 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.8 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.9 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5 Algoritmo determinista 22
5.1 Definición formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.2 Cuándo un algoritmo puede volverse no determinista . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.3 Problemas con los algoritmos deterministas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.4 Notas al pie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.5 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6 Estructura de datos 24
6.1 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6.2 Estructuras de datos en programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6.3 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7 Cola (informática) 25
7.1 Usos concretos de la cola . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.2 Información adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.3 Operaciones Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.4 Implementaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
ÍNDICE GENERAL iii
7.4.1 Colas en Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7.4.2 Colas en Maude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.4.3 Colas en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.4.4 Colas en JAVA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.4.5 Colas en C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.5 Tipos de colas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
7.6 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
7.7 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
8 Tipo de dato abstracto 28
8.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
8.2 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
8.3 Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
8.4 Separación de la interfaz e implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
8.5 Caracterización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
8.6 La abstracción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
8.7 Ejemplos de uso de TDAs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
8.8 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
9 Vector (informática) 32
9.1 Índices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
9.2 Notación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
9.3 Forma de acceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
9.4 Vectores dinámicos y estáticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
9.4.1 Ejemplos en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
9.5 Vectores multidimensionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
9.6 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
10 Pila (informática) 34
10.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
10.2 Pila como tipo abstracto de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
10.2.1 Operaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
10.2.2 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
10.2.3 Estructuras de datos relacionadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
10.3 Pilas Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
10.4 Arquitectura básica de una pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
10.5 Soporte de Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
10.6 Soporte de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
10.7 Expresión de evaluación y análisis sintáctico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
10.7.1 Tiempo de ejecución de la gestión de memoria . . . . . . . . . . . . . . . . . . . . . . . 37
10.7.2 Solucionar problemas de búsqueda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
10.8 Seguridad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
iv ÍNDICE GENERAL
10.9 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
10.10Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
11 Programa informático 38
11.1 Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
11.1.1 Paradigmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
11.1.2 Compilado o interpretando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
11.1.3 Programas que se auto-modifican . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
11.2 Ejecución y almacenamiento de los programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
11.2.1 Programas empotrados en hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
11.2.2 Programas cargados manualmente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
11.2.3 Programas generados automáticamente . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
11.2.4 Ejecución simultánea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
11.3 Categorías funcionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
11.4 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
11.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
11.6 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
11.7 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
11.8 Text and image sources, contributors, and licenses . . . . . . . . . . . . . . . . . . . . . . . . . . 43
11.8.1 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
11.8.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
11.8.3 Content license . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
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
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.
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-
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.
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
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
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
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
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.
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:
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
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.
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
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).
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.
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
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-
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
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; }
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.
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
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
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
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
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
26 CAPÍTULO 7. COLA (INFORMÁTICA)
ColaLongitud:Entero Lec:Longitud FinProp Priva-
do: Constructor: Comenzar Destructor: Terminar
FinClase
7.4.2 Colas en Maude
La ColaNV es la cola no vacía, que diferenciamos de la
cola normal a la hora de tomar en cuenta errores. A su
vez, el elemento X representa el tipo de valor que puede
contener la cola: entero, carácter, registro....
fmod COLA {X :: TRIV} is sorts ColaNV{X} Cola{X}
. subsort ColaNV{X} < Cola{X} . *** generadores op
crear : -> Cola{X} [ctor] . op encolar : X$Elt Cola{X}
-> ColaNV {X} [ctor] . *** constructores op desen-
colar : Cola{X} -> Cola{X} . *** selectores op fren-
te : ColaNV{X} -> X$Elt . *** variables var C : Co-
laNV{X} . vars E E2 : X$Elt . *** ecuaciones eq des-
encolar(crear) = crear . eq desencolar(encolar(E, crear))
= crear . eq desencolar(encolar(E, C)) = encolar(E, des-
encolar(C)) . eq frente(encolar(E, crear)) = E . eq fren-
te(encolar(E, C)) = frente(C) . endfm Especificación de
una cola de colas de enteros en Maude: view VInt from
TRIV to INT is sort Elt to Int . endv view VColaInt
from TRIV to COLA{VInt} is sort Elt to Cola{VInt}
. endv fmod COLA-COLAS-INT is protecting INT .
protecting COLA{VColaInt} . *** operaciones propias
de la cola de colas de enteros op encolarInt : Int Co-
laNV{VColaInt} -> ColaNV{VColaInt} . op desenco-
larInt : Cola{VColaInt} -> Cola{VColaInt} . op fren-
teInt : ColaNV{VColaInt} -> [Int] . *** variables var
CCNV : ColaNV{VColaInt} . var CC : Cola{VColaInt}
. var CE : Cola{VInt} . var E : Int . *** ecuaciones
eq encolarInt(E, encolar(CE, CC)) = encolar(encolar(E,
CE), CC) . eq desencolarInt (encolar(CE, crear)) = en-
colar(desencolar(CE), crear) . eq desencolarInt (enco-
lar(CE, CCNV)) = encolar(CE, desencolarInt(CCNV))
. eq frenteInt(CCNV) = frente(frente(CCNV)) . endfm
7.4.3 Colas en C++
#ifndef COLA #define COLA // Define la cola using
namespace std; template <class T> class Cola{ private:
struct Nodo{ T elemento; struct Nodo* siguiente; //
coloca el nodo en la segunda posición }* primero;
struct Nodo* ultimo; unsigned int elementos; public:
Cola(){ elementos = 0; } cout<<" Hola Mundo! "
<<endl; cout<<" Hello, World! " <<endl; ~Cola(){ while
(elementos != 0) pop(); } void push(const T& elem){
Nodo* aux = new Nodo; aux->elemento = elem; if
(elementos == 0) primero = aux; else ultimo->siguiente
= aux; ultimo = aux; ++elementos; } void pop(){ Nodo*
aux = primero; primero = primero->siguiente; delete
aux; --elementos; } T consultar() const{ return primero-
>elemento; } bool vacia() const{ return elementos == 0;
} unsigned int size() const{ return elementos; } }; #endif
7.4.4 Colas en JAVA
public void inserta(Elemento x) { Nodo Nuevo; Nuevo =
new Nodo(x, null); if (NodoCabeza == null) { NodoCa-
beza = Nuevo; } else { NodoFinal.Siguiente = Nuevo; }
NodoFinal = Nuevo; } public Elemento cabeza() throws
IllegalArgumentException { if (NodoCabeza == null) {
throw new IllegalArgumentException(); } else { return
NodoCabeza.Info; } } public Cola() { // Devuelve una
Cola vacía NodoCabeza = null; NodoFinal = null; }
7.4.5 Colas en C#
public partial class frmPrincipal { // Variables glo-
bales public static string[] Cola; public static int
Frente; public static int Final; public static int
N; [STAThread] public static void Main(string[]
args) { Application.EnableVisualStyles(); Appli-
cation.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmPrincipal()); } public frmPrin-
cipal() // Constructor { InitializeComponent(); Cola
= new string[5]; // Arreglo lineal de 5 N = 4; Frente
= −1; Final = −1; } void CmdInsercionClick(object
sender, System.EventArgs e) { frmInsercion Inser-
cion = new frmInsercion(); Insercion.Show(); } void
CmdRecorridoClick(object sender, System.EventArgs
e) { frmRecorrido Recorrido = new frmRecorrido();
Recorrido.Show(); } void CmdBusquedaClick(object
sender, EventArgs e) { frmBusqueda Busqueda = new
frmBusqueda(); Busqueda.Show(); } void CmdElimina-
cionClick(object sender, EventArgs e) { frmEliminacion
Eliminar = new frmEliminacion(); Eliminar.Show(); } }
Algoritmo Insertar(Cola, N, Frente, Final, Elemento)
void CmdInsertarClick(object sender, System.EventArgs
e) { elemento = txtInsercion.Text; // Se verifica que
haya espacio en la Cola if (frmPrincipal.Frente ==
0 && frmPrincipal.Final == frmPrincipal.N) { Mes-
sageBox.Show(“La Cola esta llena”); return; } if
(frmPrincipal.Frente == frmPrincipal.Final + 1) { Mes-
sageBox.Show(“La Cola esta llena”); return; } // Si la cola
esta vacia se inicializan punteros if (frmPrincipal.Frente
== −1) { frmPrincipal.Frente = 0; frmPrincipal.Final
= 0; } else if (frmPrincipal.Final == frmPrincipal.N)
{ frmPrincipal.Final = 0; } else { frmPrincipal.Final
= frmPrincipal.Final + 1; } // Se agrega elemento a la
Cola frmPrincipal.Cola[frmPrincipal.Final] = elemento;
txtInsercion.Text = ""; }
Algoritmo Eliminación (Cola, Frente, Final, N)
void CmdEliminarClick(object sender, EventArgs
e) { if (frmPrincipal.Frente == −1) { Message-
Box.Show(“Cola Vacia”); return; } string elemento =
frmPrincipal.Cola[frmPrincipal.Frente]; // si la cola
tiene un solo elemento if (frmPrincipal.Frente ==
7.6. VÉASE TAMBIÉN 27
frmPrincipal.Final) { frmPrincipal.Frente = −1; frm-
Principal.Final = −1; } else if (frmPrincipal.Frente
== frmPrincipal.N) { frmPrincipal.Frente = 0; } else
{ frmPrincipal.Frente = frmPrincipal.Frente + 1; }
lsEliminado.Items.Add(elemento); }
Otra forma de programar una cola en Java Por Jorge He-
rrera C
import java.util.*; public class Cola <Tipo>{ private
List<Tipo> cola; public Cola(){ cola=new Array-
List<Tipo>(); } public boolean colaVacia(){ return
cola.isEmpty(); } public void agregar(Tipo elemen-
to){ cola.add(elemento); } public Tipo sacar(){
if(colaVacia())return null; Tipo elemento=cola.get(0);
cola.remove(0); return elemento; } }// Fin de la clase
Cola
A continuación un ejemplo de una clase manejadora de la
clase Cola
public class Manejador { public static void
main(String[] args) { Cola cola=new <Inte-
ger>Cola(); System.out.println(cola.sacar());
cola.agregar(23); cola.agregar(24); co-
la.agregar(25); while(!cola.colaVacia()){ Sys-
tem.out.println(cola.sacar()); } Cola nombres=new
<String>Cola(); nombres.agregar(“Jorge”); nom-
bres.agregar(“Raquel”); nombres.agregar(“Mayra
Alejandra”); while(!nombres.colaVacia()){ Sys-
tem.out.println(nombres.sacar()); } } }// Fin de la
clase Manejadora
7.5 Tipos de colas
• Colas circulares (anillos): en las que el último ele-
mento y el primero están unidos.
• Colas de prioridad: En ellas, los elementos se atien-
den en el orden indicado por una prioridad asocia-
da a cada uno. Si varios elementos tienen la misma
prioridad, se atenderán de modo convencional según
la posición que ocupen. Hay 2 formas de implemen-
tación:
1. Añadir un campo a cada nodo con su prioridad. Re-
sulta conveniente mantener la cola ordenada por or-
den de prioridad.
2. Crear tantas colas como prioridades haya, y alma-
cenar cada elemento en su cola.
• Bicolas: son colas en donde los nodos se pueden aña-
dir y quitar por ambos extremos; se les llama DE-
QUE (Double Ended QUEue). Para representar las
bicolas lo podemos hacer con un array circular con
Inicio y Fin que apunten a cada uno de los extremos.
Hay variantes:
• Bicolas de entrada restringida: Son aquellas donde la
inserción sólo se hace por el final, aunque podemos
eliminar al inicio ó al final.
• Bicolas de salida restringida: Son aquellas donde só-
lo se elimina por el final, aunque se puede insertar
al inicio y al final.
7.6 Véase también
• Pila (estructura de datos)
• Lista (estructura de datos)
• Cola de prioridad (estructura de datos)
• Cola circular
• Bicola
7.7 Enlaces externos
Capítulo 8
Tipo de dato abstracto
Un tipo de dato abstracto (TDA) o tipo abstracto de
datos (TAD) es un modelo matemático compuesto por
una colección de operaciones definidas sobre un conjunto
de datos para el modelo.
8.1 Introducción
En el mundo de la programación existen diversos
lenguajes que se han ido creando con el paso del tiempo
y que se han perfeccionado debido a las necesidades de
los programadores de la época a la que pertenecen. Los
primeros lenguajes de programación eran de tipo lineal,
ya que un programa se recorría desde un punto marcado
como Inicio hasta llegar a un punto Fin. Con el tiempo
se fueron creando nuevos lenguajes y en nuestros días los
más utilizados son los llamados “orientados a objetos”.
Los lenguajes orientados a objetos (LOO) tienen la ca-
racterística de que no son lenguajes lineales, sino que se
forman de diversas funciones, las cuales son llamadas en
el orden en que el programa mismo las pide o el usuario
determina. Para entender mejor cómo funcionan los len-
guajes orientados a objetos, vamos a introducir un con-
cepto fundamental en las Estructuras de Datos denomi-
nado Abstracción de Datos y que es parte importante de
estos Lenguajes y de la manera en que funciona la mayo-
ría del software comercial de nuestros días.
8.2 Historia
El concepto de tipo de dato abstracto (TDA, Abstract Da-
ta Type), fue propuesto por primera vez hacia 1974 por
John Guttag y otros, pero no fue hasta 1975 que por pri-
mera vez Liskov lo propuso para el lenguaje CLU.
El lenguaje Turbo Pascal fue determinante para la común
aceptación de los TDA con la introducción de las Units,
si bien estas no cumplen con las características básicas de
un tipo de dato abstracto como por ejemplo la encapsu-
lación de los datos. El lenguaje Ada pudo implementar
exitosamente los TDAs con sus Packages. Vale recordar
que estos dos últimos lenguajes soportan formalmente la
Programación modular.
8.3 Definición
Con mucha frecuencia se utilizan los términos TDA y
Abstracción de Datos de manera equivalente, y esto es
debido a la similitud e interdependencia de ambos. Sin
embargo, es importante definir por separado los dos con-
ceptos.
Como ya se mencionó, los Lenguajes de Programación
Orientados a Objetos son lenguajes formados por dife-
rentes métodos o funciones y que son llamados en el or-
den en que el programa lo requiere, o el usuario lo desea.
La abstracción de datos consiste en ocultar las caracterís-
ticas de un objeto y obviarlas, de manera que solamente
utilizamos el nombre del objeto en nuestro programa. Es-
to es similar a una situación de la vida cotidiana. Cuando
yo digo la palabra “perro”, usted no necesita que yo le di-
ga lo que hace el perro. Usted ya sabe la forma que tiene
un perro y también sabe que los perros ladran. De mane-
ra que yo abstraigo todas las características de todos los
perros en un solo término, al cual llamo “perro”. A esto
se le llama ‘Abstracción’ y es un concepto muy útil en la
programación, ya que un usuario no necesita mencionar
todas las características y funciones de un objeto cada
vez que éste se utiliza, sino que son declaradas por sepa-
rado en el programa y simplemente se utiliza el término
abstracto (“perro”) para mencionarlo.
En el ejemplo anterior, “perro” es un Tipo de Dato Abs-
tracto y todo el proceso de definirlo, implementarlo y
mencionarlo es a lo que llamamos Abstracción de Datos.
Vamos a poner un ejemplo real de la programación.
Supongamos que en algún Lenguaje de Programación
Orientado a Objetos un pequeño programa saca el área de
un rectángulo de las dimensiones que un usuario decida.
Pensemos también que el usuario probablemente quiera
saber el área de varios rectángulos. Sería muy tedioso pa-
ra el programador definir la multiplicación de ‘base’ por
‘altura’ varias veces en el programa, además que limitaría
al usuario a sacar un número determinado de áreas. Por
ello, el programador puede crear una función denomina-
da ‘Área’, la cual va a ser llamada el número de veces que
sean necesitadas por el usuario y así el programador se
evita mucho trabajo, el programa resulta más rápido, más
eficiente y de menor longitud. Para lograr esto, se crea el
28
8.5. CARACTERIZACIÓN 29
método Área de una manera separada de la interfaz grá-
fica presentada al usuario y se estipula ahí la operación a
realizar, devolviendo el valor de la multiplicación. En el
método principal solamente se llama a la función Área y
el programa hace el resto.
Al hecho de guardar todas las características y habilida-
des de un objeto por separado se le llama Encapsulamien-
to y es también un concepto importante para entender la
estructuración de datos. Es frecuente que el Encapsula-
miento sea usado como un sinónimo del Ocultación de
información, aunque algunos creen que no es así .
8.4 Separación de la interfaz e im-
plementación
Cuando se usa en un programa de computación, un TDA
es representado por su interfaz, la cual sirve como cu-
bierta a la correspondiente implementación. La idea es
que los usuarios de un TDA tengan que preocuparse só-
lo por la interfaz, pero no por la implementación, ya que
esta puede ir cambiando con el tiempo y, si no existiera
encapsulación, afectar a los programas que usan el dato.
Esto se basa en el concepto de Ocultación de informa-
ción, una protección para el programa de decisiones de
diseño que son objeto de cambio.
La solidez de un TDA reposa en la idea de que la im-
plementación está escondida al usuario. Solo la interfaz
es pública. Esto significa que el TDA puede ser imple-
mentado de diferentes formas, pero mientras se manten-
ga consistente con la interfaz, los programas que lo usan
no se ven afectados.
Hay una diferencia, aunque a veces sutil, entre el Tipo de
Dato Abstracto y la Estructura de Dato usada en su im-
plementación. Por ejemplo, un TDA de una lista puede
ser implementado mediante un Arreglo o una Lista Enla-
zada o hasta un Árbol binario de búsqueda. Una lista es
un Tipo de Dato Abstracto con operaciones bien defini-
das (agregar elemento, agregar al final, agregar al princi-
pio, recuperar, eliminar, etc) mientras una lista enlazada
es una estructura de datos basada en punteros o referen-
cias (dependiendo del lenguaje) que puede ser usada para
crear una representación de una Lista. La Lista Enlazada
es comúnmente usada para representar una TDA Lista, y
a veces, hasta confundida. Un ejemplo es la clase Linked
List de Java, la cual ofrece una gran cantidad de métodos
que no corresponden a una Lista Enlazada “pura”, sino a
un fuerte TDA.
De forma similar, un TDA Árbol binario de búsqueda
puede ser representado de muchas maneras: Árbol bina-
rio, Árbol AVL, Árbol rojo-negro, Arreglo, etc. A pesar
de la implementación un Árbol binario siempre tiene las
mismas operaciones (insertar, eliminar, encontrar, etc.)
Separar la interfaz de la implementación no siempre sig-
nifica que el usuario ignora totalmente la implementación
de la rutina, pero lo suficiente para no depender de nin-
gún aspecto de la implementación. Por ejemplo, un TDA
puede ser creado usando un script o cualquiera que pueda
ser decompilado (como C).
En la terminología de Lenguaje Orientado a Objeto, un
TDA es una clase; una instancia de un TDA o clase, es
un objeto. Además es utilizado constantemente por pro-
gramadores de computadoras.
8.5 Caracterización
Un TDA está caracterizado por un conjunto de operacio-
nes (funciones) al cual se denomina usualmente como in-
terfaz pública y representa el comportamiento del TDA;
mientras que la implementación como la parte privada del
TDA está oculta al programa cliente que lo usa. Todos los
lenguajes de alto nivel tienen predefinidos TDA; que son
los tipos denominados simples y las estructuras predefi-
nidas, y estos tienen sus interfaces públicas que incluyen
las operaciones como la +, -, *, etc. no se necesita co-
nocer como actúan tales operadores sobre la representa-
ción interna de los tipos definidos, que además, suele ser
una implementación bastante dependiente de la máqui-
na sobre la que trabaje el compilador. Lo interesante es
que los lenguajes actuales nos van a permitir ampliar los
TDA predefinidos con otros que serán definidos por el
propio programador para adecuar así los tipos de datos a
las necesidades de los programas.
Los TDA que nos van a interesar de ahora en adelante
son aquellos que reflejen cierto comportamiento organi-
zando cierta variedad de datos estructuradamente. A esta
forma estructurada de almacenar los datos será a la que
nos refiramos para caracterizar cada TDA.
Los TDA que tienen informaciones simples pero depen-
dientes de un comportamiento estructural serán llamados
polilíticos y aquellos TDA simples, como son los tipos
predefinidos donde la información no es relacionada me-
diante ninguna estructura y no admiten más que un valor
en cada momento serán denominados TDA monolíticos.
Nótese que cuando hablemos de un TDA no haremos nin-
guna alusión al tipo de los elementos sino tan sólo a la for-
ma en que están dispuestos estos elementos. Sólo nos in-
teresa la estructura que soporta la información y sus ope-
raciones. Para determinar el comportamiento estructural
basta con observar la conducta que seguirán los datos.
Caractericemos entonces los TDA. Un TDA tendrá una
parte que será invisible al usuario la cual hay que prote-
ger y que se puede decir que es irrelevante para el uso del
usuario y está constituida tanto por la maquinaria algorít-
mica que implemente la semántica de las operaciones co-
mo por los datos que sirvan de enlace entre los elementos
del TDA, es decir, información interna necesaria para la
implementación que se esté haciendo para ese comporta-
miento del TDA. Resumiendo podemos decir, que tanto
la implementación de las operaciones como los elemen-
30 CAPÍTULO 8. TIPO DE DATO ABSTRACTO
tos internos del TDA serán privados al acceso externo y
ocultos a cualquier otro nivel.
Un TDA representa una abstracción:
• Se destacan los detalles (normalmente pocos) de la
especificación (el qué).
• Se ocultan los detalles (casi siempre numerosos) de
la implementación (el cómo).
8.6 La abstracción
La abstracción, una de las herramientas que más nos ayu-
da a la hora de solucionar un problema, es un mecanismo
fundamental para la comprensión de problemas y fenó-
menos que poseen una gran cantidad de detalles, su idea
principal consiste en manejar un problema, fenómeno,
objeto, tema o idea como un concepto general, sin consi-
derar la gran cantidad de detalles que estos puedan tener.
El proceso de abstracción presenta dos aspectos comple-
mentarios.
1. Destacar los aspectos relevantes del objeto.
2. Ignorar los aspectos irrelevantes del mismo (la irre-
levancia depende del nivel de abstracción, ya que si
se pasa a niveles más concretos, es posible que cier-
tos aspectos pasen a ser relevantes).
De modo general podemos decir que la abstracción per-
mite establecer un nivel jerárquico en el estudio de los
fenómenos, el cual se establece por niveles sucesivos de
detalles. Generalmente, se sigue un sentido descendente
de detalles, desde los niveles más generales a los niveles
más concretos.
Por ejemplo: los lenguajes de programación de alto nivel
permiten al programador abstraerse del sin fin de detalles
de los lenguajes ensambladores. Otro ejemplo, la memo-
ria de la computadora es una estructura unidimensional
formada por celdas y sin embargo trabajamos como si
fuera única. La abstracción nos brinda la posibilidad de ir
definiendo una serie de refinamientos sucesivos a nuestro
TDA y entiéndase bien que cuando decimos refinamien-
tos sucesivos nos estamos refiriendo a la estrategia que se
utiliza para descomponer un problema en subproblemas.
Conforme evoluciona el diseño de software a cada nivel
de módulos se representa un refinamiento en el nivel de
abstracción. Esto es, incluir detalles que fueron obviados
en un nivel superior, en un nivel más bajo de la jerarquía.
Veamos los diferentes tipos de abstracción que podemos
encontrar en un programa:
1. Abstracción funcional: crear procedimientos y fun-
ciones e invocarlos mediante un nombre donde se destaca
qué hace la función y se ignora cómo lo hace. El usuario
sólo necesita conocer la especificación de la abstracción
(el qué) y puede ignorar el resto de los detalles (el cómo).
2. Abstracción de datos:
• Tipo de datos: proporcionado por los leguajes de
alto nivel. La representación usada es invisible al
programador, al cual solo se le permite ver las ope-
raciones predefinidas para cada tipo.
• Tipos definidos: por el programador que posibili-
tan la definición de valores de datos más cercanos al
problema que se pretende resolver.
• TDA: para la definición y representación de tipos de
datos (valores + operaciones), junto con sus propie-
dades.
• Objetos: Son TDA a los que se añade propiedades
de reutilización y de compartición de código.
Si profundizamos más al mundo de la programación y sus
conceptos, existen dos de estos conceptos que no se deben
confundir, ellos son: tipo de datos y estructura de datos.
Un tipo de dato, en un lenguaje de programación, defi-
ne un conjunto de valores que una determinada variable
puede tomar, así como las operaciones básicas sobre di-
cho conjunto. Ahora veamos como se van relacionando
estos conceptos. Los tipos de datos constituyen un primer
nivel de abstracción, ya que no se tiene en cuenta cómo
se implementan o se representan realmente la informa-
ción sobre la memoria de la máquina. Para el usuario, el
proceso de implementación o representación es invisible.
Veamos entonces que son las estructuras de datos. Las
estructuras de datos son colecciones de variables, no ne-
cesariamente del mismo tipo, relacionadas entre sí de al-
guna forma. Las estructuras de datos están caracterizadas
por el tipo de dato de los elementos guardados en la es-
tructura y por la relación definida sobre estos elementos.
Al nivel de las estructuras de datos son totalmente irre-
levantes las operaciones sobre un elemento en particular,
solamente tienen carácter relevante las operaciones que
envuelvan la estructura de forma global.
La abstracción de datos es la característica de un sistema
de bases de datos, que permite al usuario o programador
operar con los datos sin necesidad de conocer detalles que
para él no son de “importancia”, ofreciendo así una visión
abstracta de estos. Para cumplir con tal fin se han definido
diferentes niveles de abstracción: [1]
• Nivel Físico. Determina como están almacenados fí-
sicamente los datos (pistas, sectores, cilindros), re-
presenta el nivel más bajo.
• Nivel Lógico o Conceptual. Determina la organiza-
ción de los archivos. Índices, llaves, orden de cam-
pos, relaciones, tipos de datos.
• Nivel de Vistas. Oculta parte de la información a los
usuarios, es decir hace visible solo una parte de la
base de datos.
8.8. REFERENCIAS 31
8.7 Ejemplos de uso de TDAs
Algunos ejemplos del uso de TDAs en programación son:
• Conjuntos: Implementación de conjuntos con sus
operaciones básicas (unión, intersección y diferen-
cia), operaciones de inserción, borrado, búsqueda...
• Árboles Binarios de Búsqueda: Implementación
de árboles de elementos, utilizados para la represen-
tación interna de datos complejos. Aunque siempre
se los toma como un TDA separado son parte de la
familia de los grafos.
• Pilas y Colas: Implementación de los algoritmos
FIFO y LIFO.
• Grafos: Implementación de grafos; una serie de vér-
tices unidos mediante una serie de arcos o aristas.
8.8 Referencias
[1] http://blogdecomputacion.com/blog/2010/08/21/
que-es-la-abstraccion-de-datos-y-modelos-de-datos/
Capítulo 9
Vector (informática)
0 1 2 3 4 5 6 7 8 9
Matriz unidimensional con 10 elementos.
En programación, una matriz o vector (llamado en inglés
array) es una zona de almacenamiento continuo, que con-
tiene una serie de elementos del mismo tipo, los elemen-
tos de la matriz. Desde el punto de vista lógico una matriz
se puede ver como un conjunto de elementos ordenados
en fila (o filas y columnas si tuviera dos dimensiones).
En principio, se puede considerar que todas las matrices
son de una dimensión, la dimensión principal, pero los
elementos de dicha fila pueden ser a su vez matrices (un
proceso que puede ser recursivo), lo que nos permite ha-
blar de la existencia de matrices multidimensionales, aun-
que las más fáciles de imaginar son los de una, dos y tres
dimensiones.
Estas estructuras de datos son adecuadas para situacio-
nes en las que el acceso a los datos se realice de forma
aleatoria e impredecible. Por el contrario, si los elemen-
tos pueden estar ordenados y se va a utilizar acceso se-
cuencial sería más adecuado utilizar una lista, ya que esta
estructura puede cambiar de tamaño fácilmente durante
la ejecución de un programa.
9.1 Índices
Todo vector se compone de un determinado número de
elementos. Cada elemento es referenciado por la posición
que ocupa dentro del vector. Dichas posiciones son llama-
das índice y siempre son correlativos. Existen tres formas
de indexar los elementos de una matriz:
• Indexación base-cero (0): en este modo el primer
elemento del vector será la componente cero ('0')
del mismo, es decir, tendrá el índice '0'. En conse-
cuencia, si el vector tiene 'n' componentes la última
tendrá como índice el valor 'n-1'. El lenguaje C es un
ejemplo típico que utiliza este modo de indexación.
• Indexación base-uno (1): en esta forma de indexa-
ción, el primer elemento de la matriz tiene el índice
'1' y el último tiene el índice 'n' (para una matriz de
'n' componentes).
• Indexación base-n (n): este es un modo versátil de
indexación en la que el índice del primer elemen-
to puede ser elegido libremente, en algunos lengua-
jes de programación se permite que los índices pue-
dan ser negativos e incluso de cualquier tipo escalar
(también cadenas de caracteres).
9.2 Notación
La representación de un elemento en un vector se sue-
le hacer mediante el identificador del vector seguido del
índice entre corchetes, paréntesis o llaves:
Aunque muchas veces en pseudocódigo y en libros de
matemática se representan como letras acompañadas de
un subíndice numérico que indica la posición a la que se
quiere acceder. Por ejemplo, para un vector "A":
A0, A1, A2, ... (vector unidimensional)
9.3 Forma de acceso
La forma de acceder a los elementos de la matriz es di-
recta; esto significa que el elemento deseado es obtenido
a partir de su índice y no hay que ir buscándolo elemento
por elemento (en contraposición, en el caso de una lis-
ta, para llegar, por ejemplo, al tercer elemento hay que
acceder a los dos anteriores o almacenar un apuntador o
puntero que permita acceder de manera rápida a ese ele-
mento).
Para trabajar con vectores muchas veces es preciso reco-
rrerlos. Esto se realiza por medio de bucles. El siguiente
pseudocódigo muestra un algoritmo típico para recorrer
un vector y aplicar una función ' f(...) ' a cada una de las
componentes del vector:
i = 0 mientras (i < longitud) //Se realiza alguna opera-
ción con el vector en la i-ésima posición f(v[i]) i=i+1
fin_mientras
32
9.5. VECTORES MULTIDIMENSIONALES 33
9.4 Vectores dinámicos y estáticos
Lo habitual es que un vector tenga una cantidad fija de
memoria asignada, aunque dependiendo del tipo de vec-
tor y del lenguaje de programación un vector podría tener
una cantidad variable de datos. En este caso, se les deno-
mina vectores dinámicos, en oposición, a los vectores
con una cantidad fija de memoria asignada se los deno-
mina vectores estáticos.
El uso de vectores dinámicos requiere realizar una apro-
piada gestión de memoria dinámica. Un uso incorrecto
de los vectores dinámicos, o mejor dicho, una mala ges-
tión de la memoria dinámica, puede conducir a una fuga
de memoria. Al utilizar vectores dinámicos siempre ha-
brá que liberar la memoria utilizada cuando ésta ya no se
vaya a seguir utilizando.
Lenguajes más modernos y de más alto nivel, cuentan con
un mecanismo denominado recolector de basura (como es
el caso de Java) que permiten que el programa decida si
debe liberar el espacio basándose en si se va a utilizar en
el futuro o no un determinado objeto.
9.4.1 Ejemplos en C
• Declaración en C/C++ de un vector estático.
int main(void) { int i, v[5]; // v[5] es un vector de 5
componentes for(i=0; i<5; i++) { v[i] = 0; // Asignamos
un valor printf("%dn”, v[i]); printf("n”); // Crea una
nueva línea } return 0 }
• Declaración en C/C++ de un vector estático utili-
zando aritmética de punteros.
Siendo el identificador del vector, un puntero constante
que contiene la dirección del comienzo del vector (vec-
tor[0], primer elemento)
int main(void) { int i, v[5]; // v[5] es un vector de
5 componentes for(i=0; i<5; i++) { *(v + i) = 0; //
Asignamos un valor en la dirección (vector + ((índice *
sizeof (int) cantidad de bytes de desplazamiento desde la
base.) printf("%dn”, *(vector + i)); printf("n”); // Crea
una nueva línea } return 0 }
• Declaración en C++ de un vector de STL:
#include <vector> vector<int> v; // Si no se espe-
cifica el tamaño inicial es 0 for(int i=0 ;i<5 ;i++) {
v.push_back(2*i); // inserta un elemento al final del
vector }
El ejemplo anterior está hecho para el lenguaje C++. En
C, para crear vectores dinámicos se tendrían que utilizar
las instrucciones malloc y realloc para reservar memoria
de forma dinámica (ver biblioteca stdlib.h), y la función
free para liberar la memoria utilizada.
Resultado:
El resultado de los dos ejemplos es el mismo vector.
9.5 Vectores multidimensionales
En Basic, Java y otros lenguajes es posible declarar matri-
ces multidimensionales, entendiéndolas como un vector
de x dimensión. En dichos casos en número de elementos
del vector es el producto resultante de cada dimensión.
Por ejemplo el vector v(4,1) tiene 10 elementos se calcula
del siguiente modo: (0-4) * (0-1). Los elementos de la
primera dimensión del vector contiene 5 elementos que
van del '0' al '4' y la 2º dimensión tiene 2 elementos que
van desde '0' a '1'. Los elementos serían accedidos del
siguiente modo:
elemento 1: (0,0)
elemento 2: (0,1)
elemento 3: (1,0)
...
elemento 8: (3,1)
elemento 9: (4,0)
elemento 10: (4,1)
9.6 Véase también
• Estructura de datos
• Registro (estructura de datos)
• Programación orientada a objetos
• Gráfico vectorial
• Tupla
Capítulo 10
Pila (informática)
DesapilarApilar
Representación simplificada de una pila
Pilas para niños
Una pila (stack en inglés) es una lista ordenada o
estructura de datos en la que el modo de acceso a sus ele-
mentos es de tipo LIFO (del inglés Last In First Out, últi-
mo en entrar, primero en salir) que permite almacenar
y recuperar datos. Esta estructura se aplica en multitud
de ocasiones en el área de informática debido a su sim-
plicidad y ordenación implícita de la propia estructura.
Para el manejo de los datos se cuenta con dos operaciones
básicas: apilar (push), que coloca un objeto en la pila, y
su operación inversa, retirar (o desapilar, pop), que retira
el último elemento apilado.
En cada momento sólo se tiene acceso a la parte superior
de la pila, es decir, al último objeto apilado (denominado
TOS, Top of Stack en inglés). La operación retirar per-
mite la obtención de este elemento, que es retirado de la
pila permitiendo el acceso al siguiente (apilado con ante-
rioridad), que pasa a ser el nuevo TOS.
Por analogía con objetos cotidianos, una operación apilar
equivaldría a colocar un plato sobre una pila de platos, y
una operación retirar a retirarlo.
Las pilas suelen emplearse en los siguientes contextos:
• Evaluación de expresiones en notación postfija
(notación polaca inversa).
• Reconocedores sintácticos de lenguajes indepen-
dientes del contexto
• Implementación de recursividad.
10.1 Historia
El método de pila para la evaluación de expresiones fue
propuesto en 1955 y dos años después patentado por Frie-
drich L. Bauer, quién recibió en 1988 el premio “IEEE
Computer Society Pioneer Award” por su trabajo en el
desarrollo de dicha estructura de datos.
10.2 Pila como tipo abstracto de
datos
A modo de resumen tipo de datos, la pila es un conte-
nedor de nodos y tiene dos operaciones básicas: push (o
apilar) y pop (o desapilar). 'Push' añade un nodo a la par-
te superior de la pila, dejando por debajo el resto de los
nodos. 'Pop' elimina y devuelve el actual nodo superior de
la pila. Una metáfora que se utiliza con frecuencia es la
idea de una pila de platos en una cafetería con muelle de
pila. En esa serie, sólo la primera placa es visible y acce-
sible para el usuario, todas las demás placas permanecen
ocultas. Como se añaden las nuevas placas, cada nueva
placa se convierte en la parte superior de la pila, escondi-
dos debajo de cada plato, empujando a la pila de placas.
34
10.4. ARQUITECTURA BÁSICA DE UNA PILA 35
A medida que la placa superior se elimina de la pila, la
segunda placa se convierte en la parte superior de la pila.
Dos principios importantes son ilustrados por esta metá-
fora: En primer lugar la última salida es un principio, la
segunda es que el contenido de la pila está oculto. Sólo la
placa de la parte superior es visible, por lo que para ver
lo que hay en la tercera placa, el primer y segundo platos
tendrán que ser retirados.
10.2.1 Operaciones
Una pila cuenta con 2 operaciones imprescindibles: apilar
y desapilar, a las que en las implementaciones modernas
de las pilas se suelen añadir más de uso habitual.
• Crear: se crea la pila vacía. (constructor)
• Tamaño: regresa el número de elementos de la pila.
(size)
• Apilar: se añade un elemento a la pila.(push)
• Desapilar: se elimina el elemento frontal de la pi-
la.(pop)
• Cima: devuelve el elemento que esta en la cima de
la pila. (top o peek)
• Vacía: devuelve cierto si la pila está sin elementos o
falso en caso de que contenga uno. (empty).
10.2.2 Implementación
Un requisito típico de almacenamiento de una pila de n
elementos es O(n). El requisito típico de tiempo de O(1)
las operaciones también son fáciles de satisfacer con un
array o con listas enlazadas simples.
10.2.3 Estructuras de datos relacionadas
El tipo base de la estructura FIFO (el primero en entrar
es el primero en salir)es la cola, y la combinación de las
operaciones de la pila y la cola es proporcionado por el
deque. Por ejemplo, el cambio de una pila en una cola
en un algoritmo de búsqueda puede cambiar el algoritmo
de búsqueda en primera profundidad (en inglés, DFS) por
una búsqueda en amplitud (en inglés, BFS). Una pila aco-
tada es una pila limitada a un tamaño máximo impuesto
en su especificación.
10.3 Pilas Hardware
Un uso muy común de las pilas a nivel de arquitectura
hardware es la asignación de memoria.
10.4 Arquitectura básica de una pi-
la
Una pila típica es un área de la memoria de los compu-
tadores con un origen fijo y un tamaño variable. Al prin-
cipio, el tamaño de la pila es cero. Un puntero de pila, por
lo general en forma de un registro de hardware, apunta a
la más reciente localización en la pila; cuando la pila tie-
ne un tamaño de cero, el puntero de pila de puntos en el
origen de la pila.
Las dos operaciones aplicables a todas las pilas son:
• Una operación apilar, en el que un elemento de datos
se coloca en el lugar apuntado por el puntero de pila,
y la dirección en el puntero de pila se ajusta por el
tamaño de los datos de partida.
• Una operación desapilar: un elemento de datos en
la ubicación actual apuntado por el puntero de pila
es eliminado, y el puntero de pila se ajusta por el
tamaño de los datos de partida.
Hay muchas variaciones en el principio básico de las ope-
raciones de pila. Cada pila tiene un lugar fijo en la me-
moria en la que comienza. Como los datos se añadirán a
la pila, el puntero de pila es desplazado para indicar el es-
tado actual de la pila, que se expande lejos del origen (ya
sea hacia arriba o hacia abajo, dependiendo de la aplica-
ción concreta).
Por ejemplo, una pila puede comenzar en una posición
de la memoria de mil, y ampliar por debajo de las direc-
ciones, en cuyo caso, los nuevos datos se almacenan en
lugares que van por debajo de 1000, y el puntero de pila
se decrementa cada vez que un nuevo elemento se agre-
ga. Cuando un tema es eliminado de la pila, el puntero de
pila se incrementa.
Los punteros de pila pueden apuntar al origen de una pila
o de un número limitado de direcciones, ya sea por enci-
ma o por debajo del origen (dependiendo de la dirección
en que crece la pila), sin embargo el puntero de pila no
puede cruzar el origen de la pila. En otras palabras, si el
origen de la pila está en la dirección 1000 y la pila crece
hacia abajo (hacia las direcciones 999, 998, y así sucesi-
vamente), el puntero de pila nunca debe ser incrementado
más allá de 1000 (para 1001, 1002, etc.) Si un desapilar
operación en la pila hace que el puntero de pila se deje
atrás el origen de la pila, una pila se produce desborda-
miento. Si una operación de apilar hace que el puntero de
pila incremente o decremente más allá del máximo de la
pila, en una pila se produce desbordamiento.
La pila es visualizada ya sea creciente de abajo hacia arri-
ba (como pilas del mundo real), o, con el máximo elemen-
to de la pila en una posición fija, o creciente, de izquierda
a derecha, por lo que el máximo elemento se convierte en
el máximo a “la derecha”. Esta visualización puede ser in-
dependiente de la estructura real de la pila en la memoria.
36 CAPÍTULO 10. PILA (INFORMÁTICA)
Esto significa que rotar a la derecha es mover el primer
elemento a la tercera posición, la segunda a la primera y
la tercera a la segunda. Aquí hay dos equivalentes visua-
lizaciones de este proceso:
Manzana Plátano Plátano ==rotar a la derecha==> Fresa
Fresa Manzana
Fresa Manzana Plátano ==rotar a la izquierda==> Fresa
Manzana Plátano
Una pila es normalmente representada en los ordenadores
por un bloque de celdas de memoria, con los “de abajo”
en una ubicación fija, y el puntero de pila de la dirección
actual de la “cima” de células de la pila. En la parte supe-
rior e inferior se utiliza la terminología con independen-
cia de que la pila crece realmente a la baja de direcciones
de memoria o direcciones de memoria hacia mayores.
Apilando un elemento en la pila,se ajusta el puntero de
pila por el tamaño de elementos (ya sea decrementar o
incrementar, en función de la dirección en que crece la
pila en la memoria), que apunta a la próxima celda, y
copia el nuevo elemento de la cima en área de la pila.
Dependiendo de nuevo sobre la aplicación exacta, al fi-
nal de una operación de apilar, el puntero de pila puede
señalar a la siguiente ubicación no utilizado en la pila, o
tal vez apunte al máximo elemento de la pila. Si la pila
apunta al máximo elemento de la pila, el puntero de pila
se actualizará antes de que un nuevo elemento se apile, si
el puntero que apunta a la próxima ubicación disponible
en la pila, que se actualizará después de que el máximo
elemento se apile en la pila.
Desapilando es simplemente la inversa de apilar. El pri-
mer elemento de la pila es eliminado y el puntero de pila
se actualiza, en el orden opuesto de la utilizada en la ope-
ración de apilar.
10.5 Soporte de Hardware
Muchas CPUs tienen registros que se pueden utilizar co-
mo punteros de pila. Algunos, como el Intel x86, tienen
instrucciones especiales que implícitamente el uso de un
registro dedicado a la tarea de ser un puntero de pila.
Otros, como el DEC PDP-11 y de la familia 68000 de
Motorola tienen que hacer frente a los modos de hacer
posible la utilización de toda una serie de registros como
un puntero de pila. La serie Intel 80x87 numérico de co-
processors tiene un conjunto de registros que se puede ac-
ceder ya sea como una pila o como una serie de registros
numerados. Algunos microcontroladores, por ejemplo al-
gunos PICs, tienen un fondo fijo de pila que no es direc-
tamente accesible. También hay una serie de microproce-
sadores que aplicar una pila directamente en el hardware:
• Computer vaqueros MuP21
• Harris RTX línea
• Novix NC4016
Muchas pilas basadas en los microprocesadores se uti-
lizan para aplicar el lenguaje de programación Forth en
el nivel de microcódigo. Pila también se utilizaron co-
mo base de una serie de mainframes y miniordenadores.
Esas máquinas fueron llamados pila de máquinas, el más
famoso es el Burroughs B5000
10.6 Soporte de Software
En programas de aplicación escrito en un lenguaje de al-
to nivel, una pila puede ser implementada de manera efi-
ciente, ya sea usando vectores o listas enlazadas. En LISP
no hay necesidad de aplicar la pila, puesto que las funcio-
nes apilar y desapilar están disponibles para cualquier lis-
ta. Adobe PostScript también está diseñada en torno a una
pila que se encuentra directamente visible y manipuladas
por el programador. El uso de las pilas está muy presente
en el desarrollo de software por ello la importancia de las
pilas como tipo abstracto de datos.
10.7 Expresión de evaluación y
análisis sintáctico
Se calcula empleando la notación polaca inversa utilizan-
do una estructura de pila para los posibles valores. Las
expresiones pueden ser representadas en prefijo, infijo,
postfijo. La conversión de una forma de la expresión a
otra forma necesita de una pila. Muchos compiladores
utilizan una pila para analizar la sintaxis de las expresio-
nes, bloques de programa, etc. Antes de traducir el código
de bajo nivel. La mayoría de los lenguajes de programa-
ción son de contexto libre de los idiomas que les permite
ser analizados con máquinas basadas en la pila.
Por ejemplo, el cálculo: ((1 + 2) * 4) + 3, puede ser ano-
tado como en notación postfija con la ventaja de no pre-
valecer las normas y los paréntesis necesario:
1 2 + 4 * 3 +
La expresión es evaluada de izquierda a derecha utilizan-
do una pila:
• Apilar cuando se enfrentan a un operando y
• Desafilar dos operandos y evaluar el valor cuando se
enfrentan a una operación.
• Apilar el resultado.
De la siguiente manera (la Pila se muestra después de que
la operación se haya llevado a cabo):
ENTRADA OPERACIÓN PILA 1 Apilar operando 1 2
Apilar operando 1, 2 + Añadir 3 4 Apilar operando 3, 4
* Multiplicar 12 3 Apilar operando 12, 3 + Añadir 15
El resultado final, 15, se encuentra en la parte superior de
la pila al final del cálculo.
10.8. SEGURIDAD 37
10.7.1 Tiempo de ejecución de la gestión de
memoria
Artículo principal: Pila basada en la asignación de memo-
ria y Pila máquina. Una serie de lenguajes de programa-
ción están orientadas a la pila, lo que significa que la ma-
yoría definen operaciones básicas (añadir dos números, la
impresión de un carácter) cogiendo sus argumentos de la
pila, y realizando de nuevo los valores de retorno en la pi-
la. Por ejemplo, PostScript tiene una pila de retorno y un
operando de pila, y también tiene un montón de gráficos
estado y un diccionario de pila.
Forth utiliza dos pilas, una para pasar argumentos y una
subrutina de direcciones de retorno. El uso de una pila
de retorno es muy común, pero el uso poco habitual de
un argumento para una pila legible para humanos es el
lenguaje de programación Forth razón que se denomina
una pila basada en el idioma.
Muchas máquinas virtuales también están orientadas ha-
cia la pila, incluida la p-código máquina y la máquina vir-
tual Java.
Casi todos los entornos de computación de tiempo de eje-
cución de memoria utilizan una pila especial PILA para
tener información sobre la llamada de un procedimiento o
función y de la anidación con el fin de cambiar al contexto
de la llamada a restaurar cuando la llamada termina. Ellos
siguen un protocolo de tiempo de ejecución entre el que
llama y el llamado para guardar los argumentos y el valor
de retorno en la pila. Pila es una forma importante de apo-
yar llamadas anidadas o a funciones recursivas. Este tipo
de pila se utiliza implícitamente por el compilador para
apoyar CALL y RETURN estados (o sus equivalentes),
y no es manipulada directamente por el programador.
Algunos lenguajes de programación utilizar la pila para
almacenar datos que son locales a un procedimiento. El
espacio para los datos locales se asigna a los temas de la
pila cuando el procedimiento se introduce, y son borradas
cuando el procedimiento termina. El lenguaje de progra-
mación C es generalmente aplicado de esta manera. Uti-
lizando la misma pila de los datos y llamadas de proce-
dimiento tiene importantes consecuencias para la segu-
ridad (ver más abajo), de los que un programador debe
ser consciente, a fin de evitar la introducción de graves
errores de seguridad en un programa.
10.7.2 Solucionar problemas de búsqueda
La búsqueda de la solución de un problema, es indepen-
dientemente de si el enfoque es exhaustivo u óptimo, ne-
cesita espacio en la pila. Ejemplos de búsqueda exhaus-
tiva métodos son fuerza bruta y backtraking. Ejemplos
de búsqueda óptima a explorar métodos,son branch and
bound y soluciones heurísticas. Todos estos algoritmos
utilizan pilas para recordar la búsqueda de nodos que se
han observado, pero no explorados aún. La única alter-
nativa al uso de una pila es utilizar la recursividad y de-
jar que el compilador sea recursivo (pero en este caso el
compilador todavía está utilizando una pila interna). El
uso de pilas es frecuente en muchos problemas, que van
desde almacenar la profundidad de los árboles hasta re-
solver crucigramas o jugar al ajedrez por ordenador. Al-
gunos de estos problemas pueden ser resueltos por otras
estructuras de datos como una cola.
10.8 Seguridad
La seguridad a la hora de desarrollar software usando es-
tructuras de datos de tipo pila es un factor a tener en cuen-
ta debido a ciertas vulnerabilidades que un uso incorrecto
de éstas puede originar en la seguridad de nuestro soft-
ware o en la seguridad del propio sistema que lo ejecu-
ta. Por ejemplo, algunos lenguajes de programación usan
una misma pila para almacenar los datos para un proce-
dimiento y el enlace que permite retornar a su invocador.
Esto significa que el programa introduce y extrae los da-
tos de la misma pila en la que se encuentra la información
crítica con las direcciones de retorno de las llamadas a
procedimiento, supongamos que al introducir datos en la
pila lo hacemos en una posición errónea de manera que
introducimos datos de mayor tamaño al soportado por la
pila corrompiendo así las llamadas a procedimientos, pro-
vocaríamos un fallo en nuestro programa. Ésta técnica
usada de forma maliciosa (es similar, pero en otro ámbi-
to al buffer overflow) permitiría a un atacante modificar
el funcionamiento normal de nuestro programa y nuestro
sistema, y es al menos una técnica útil si no lo evitamos
en lenguajes muy populares como el ejemplo C++.
10.9 Véase también
• Listas
• Pilas Acotadas
• Colas
10.10 Enlaces externos
• Estructuras de datos/Pilas y colas, en Wikibooks
(inglés)
• Distintas implementaciones del manejo de pilas en
RosettaCode.org
Capítulo 11
Programa informático
Un programa informático escrito en un estilo orientado a objetos.
Un programa informático o programa de compu-
tadora es una secuencia de instrucciones, escritas pa-
ra realizar una tarea específica en una computadora.[1]
Este dispositivo requiere programas para funcionar, por
lo general ejecutando las instrucciones del programa en
un procesador central.[2]
El programa tiene un forma-
to ejecutable que la computadora puede utilizar directa-
mente para ejecutar las instrucciones. El mismo progra-
ma en su formato de código fuente legible para huma-
nos, del cual se derivan los programas ejecutables (por
ejemplo, compilados), le permite a un programador estu-
diar y desarrollar sus algoritmos. Una colección de pro-
gramas de computadora y datos relacionados se conoce
como software.
Generalmente el código fuente lo escriben profesionales
conocidos como programadores de computadora.[3]
Es-
te código se escribe en un lenguaje de programación que
sigue uno de los siguientes dos paradigmas: imperativo
o declarativo, y que posteriormente puede ser converti-
do en un archivo ejecutable (usualmente llamado un pro-
grama ejecutable o un binario) por un compilador y más
tarde ejecutado por una unidad central de procesamien-
to. Por otra parte, los programas de computadora se pue-
den ejecutar con la ayuda de un intérprete, o pueden ser
empotrados directamente en hardware.
De acuerdo a sus funciones, los programas informáti-
cos se clasifican en software de sistema y software de apli-
cación. En las computadoras actuales, al hecho de ejecu-
tar varios programas de forma simultánea y eficiente, se
le conoce como multitarea.
11.1 Programación
La programación de computadoras es el proceso iterati-
vo de escribir o editar código fuente. Dicha edición de
código fuente implica probar, analizar y perfeccionar, y,
a veces, coordinar con otros programadores, en el caso
de un programa desarrollado en conjunto. Una persona
que practica esta técnica se le conoce como programador
de computadoras, desarrollador de software, o codifica-
dor. El proceso, a veces a largo plazo, de programación de
computadoras normalmente se lo conoce como desarrollo
de software. El término ingeniería de software se está
convirtiendo en muy popular, ya que esta actividad es vis-
ta como una disciplina de ingeniería.
11.1.1 Paradigmas
Los programas de ordenador se pueden clasificar según
el paradigma del lenguaje de programación utilizado pa-
ra producirlos. Dos de los principales paradigmas son
imperativos y declarativos.
Los programas escritos con un lenguaje imperativo espe-
cifican un algoritmo utilizando declaraciones, expresio-
nes e informes.[4]
Una declaración asocia un nombre de
variable a un tipo de datos. Por ejemplo: var x: integer; .
Una expresión produce un valor. Por ejemplo: 2 + 2 pro-
duce 4. Por último, una declaración puede asignar una
expresión a una variable o usar el valor de una variable
para alterar las estructuras de control del programa. Por
ejemplo: x := 2 + 2; if x = 4 then hacer_algo(); Una crí-
tica de los lenguajes imperativos es el efecto secundario
de una sentencia de asignación en una clase de variables
llamadas variables no locales.[5]
38
11.2. EJECUCIÓN Y ALMACENAMIENTO DE LOS PROGRAMAS 39
Los programas escritos en un lenguaje declarativo espe-
cifican las propiedades que tienen o que deben cumplir-
se para la salida. No especifican detalles expresados en
términos de flujo de control de la máquina de ejecución
pero sí de las relaciones matemáticas entre los objetos
declarados y sus propiedades. Los lenguajes funcionales
y lógicos son dos amplias categorías de lenguajes decla-
rativos. El principio detrás de los lenguajes funcionales
(como Haskell) es el de no permitir efectos secundarios,
lo que hace que sea más fácil para razonar sobre los pro-
gramas como si se tratasen de funciones matemáticas.[5]
El principio detrás de los lenguajes lógicos (como Prolog)
es definir el problema a ser resuelto - la meta - y dejar la
solución detallada al propio sistema Prolog.[6]
El objetivo
se define proporcionando la lista de sub-objetivos. Luego,
cada subobjetivo se define más arriba, proporcionando la
lista de sus sub-objetivos, etc. Si la ruta de sub-objetivos
no encuentra una solución, entonces ese subobjetivo se
retrocede y otra vía se intenta sistemáticamente.
La forma en que se crea el programa puede ser textual o
visual. En un programa de lenguaje visual, los elementos
en vez de ser textualmente especificados son manipulados
gráficamente.
11.1.2 Compilado o interpretando
Un programa de computadora bajo la forma de lengua-
je de programación de computadoras legible por un hu-
mano, se lo llama código fuente. Dicho código fuen-
te se puede convertir en una imagen ejecutable por un
compilador o ejecutarse inmediatamente con la ayuda de
un intérprete.
Cualquiera de los programas compilados o interpretados
pueden ser ejecutados en un proceso por lotes sin inter-
vención humana, pero los programas interpretados le per-
miten al usuario escribir comandos en una sesión interac-
tiva. En este caso, los programas son los comandos sepa-
rados, cuya ejecución se produce secuencialmente, y por
lo tanto simultáneamente. Cuando se utiliza un lenguaje
para dar órdenes a una aplicación de software (como un
shell de Unix u otra interfaz de línea de comandos), se le
llama un lenguaje de scripts.
Los compiladores se utilizan para traducir el código fuen-
te de un lenguaje de programación, ya sea en código obje-
to o código máquina.[7]
El código objeto de objeto nece-
sita procesamiento adicional para convertirse en código
máquina, y el código máquina es el código nativo de la
unidad central de procesamiento, listo para su ejecución.
Los programas de computadora compilados se conocen
comúnmente como ejecutables, imágenes binarias, o sim-
plemente como binarios — una referencia al formato de
archivo binario utilizado para almacenar el código ejecu-
table.
Los programas de computadora — interpretados en un lo-
te o una sesión interactiva — o bien se descodifican y lue-
go ejecutados inmediatamente o se decodifican en alguna
representación intermedia eficiente para la ejecución fu-
tura. BASIC, Perl y Python son ejemplos de programas de
computadora ejecutados inmediatamente. Por otra parte,
los programas de computadora de Java se compilan antes
de tiempo y se almacena como un código independien-
te de la máquina llamado bytecode. Entonces, dicho by-
tecode es ejecutado a petición de un intérprete llamado
máquina virtual.
La principal desventaja de los intérpretes es que los pro-
gramas de computadora corren más lento que cuando son
compilados. La interpretación de código resulta más lenta
que la ejecución de la versión compilada porque el intér-
prete debe decodificar cada declaración cada vez que se
carga y luego realizar la acción deseada. Sin embargo, el
desarrollo de software puede ser más rápido usando un in-
térprete porque la prueba es inmediata cuando se omite el
paso de la compilación. Otra desventaja de los intérpretes
es que debe estar presente al menos uno en la computado-
ra durante la ejecución del programa de computadora. Por
el contrario, los programas de computadora compilados
no necesitan compilador presente durante la ejecución.
No se requieren propiedades de un lenguaje de progra-
mación si se está compilado exclusivamente o interpre-
tándose exclusivamente. Por lo general, la clasificación
refleja el método más popular de ejecución del lenguaje.
Por ejemplo, BASIC se considera un lenguaje interpreta-
do y C un lenguaje compilado, a pesar de la existencia de
compiladores de BASIC e intérpretes de C. Algunos sis-
temas utilizan compilación en tiempo de ejecución (JIT)
mediante la cual las secciones de la fuente se compilan
'sobre la marcha' y se almacenan para ejecuciones poste-
riores.
11.1.3 Programas que se auto-modifican
Un programa informático en ejecución normalmente es
tratado como algo diferente de los datos con los cuales
opera. Sin embargo, en algunos casos ésta distinción es
ambigua, especialmente cuando un programa se modi-
fica a sí mismo. El programa modificado es secuencial-
mente ejecutado como parte del mismo programa. El có-
digo que se auto-modifica es posible para programas es-
critos en código máquina, Lenguaje ensamblador, Lisp,
C, COBOL, PL/1 y Prolog y JavaScript (la función eval),
entre otros.
11.2 Ejecución y almacenamiento
de los programas
Típicamente, los programas se almacenan en una
memoria no volátil (por ejemplo un disco), para que luego
el usuario de la computadora, directa o indirectamente,
solicite su ejecución. Al momento de dicha solicitud, el
programa es cargado en la memoria de acceso aleatorio
40 CAPÍTULO 11. PROGRAMA INFORMÁTICO
o RAM del equipo, bajo el control del software llama-
do sistema operativo, el cual puede acceder directamente
al procesador. El procesador ejecuta (corre) el programa,
instrucción por instrucción hasta que termina. A un pro-
grama en ejecución se le suele llamar también proceso.
Un programa puede terminar su ejecución en forma nor-
mal o por causa de un error, dicho error puede ser de
software o de hardware.
11.2.1 Programas empotrados en hardwa-
re
El microcontrolador a la derecha de la Memoria USB está con-
trolada por un firmware empotrado.
Algunos programas están empotrados en el hardware.
Una computadora con arquitectura de programas alma-
cenados requiere un programa inicial almacenado en su
ROM para arrancar. El proceso de arranque es para iden-
tificar e inicializar todos los aspectos del sistema, desde
los registros del procesador, controladores de dispositi-
vos hasta el contenido de la memoria RAM.[8]
Seguido
del proceso de inicialización, este programa inicial carga
al sistema operativo e inicializa al contador de programa
para empezar las operaciones normales. Independiente de
la computadora, un dispositivo de hardware podría tener
firmware empotrado para el control de sus operaciones.
El firmware se utiliza cuando se espera que el programa
cambie en raras ocasiones o nunca, o cuando el programa
no debe perderse cuando haya ausencia de energía.[9]
11.2.2 Programas cargados manualmente
Los programas históricamente se cargaron manualmen-
te al procesador central mediante interruptores. Una ins-
trucción era representada por una configuración de es-
tado abierto o cerrado de los interruptores. Después de
establecer la configuración, se ejecutaba un botón de eje-
cución. Este proceso era repetitivo. También, histórica-
mente los programas se cargaban manualmente median-
te una cinta de papel o tarjetas perforadas. Después de
que el programa se cargaba, la dirección de inicio se es-
Interruptores para la carga manual en una Data General Nova
3.
tablecía mediante interruptores y el botón de ejecución se
presionaba.[10]
11.2.3 Programas generados automática-
mente
La programación automática es un estilo de
programación que crea código fuente mediante
clases genéricas, prototipos, plantillas, aspectos, y
generadores de código para aumentar la productivi-
dad del programador. El código fuente se genera con
herramientas de programación tal como un procesador
de plantilla o un IDE. La forma más simple de un
generador de código fuente es un procesador macro, tal
como el preprocesador de C, que reemplaza patrones de
código fuente de acuerdo a reglas relativamente simples.
Un motor de software da de salida código fuente o
lenguaje de marcado que simultáneamente se vuelve
la entrada de otro proceso informático. Podemos pen-
sar como analogía un proceso manejando a otro sien-
do el código máquina quemado como combustible. Los
servidores de aplicaciones son motores de software que
entregan aplicaciones a computadoras cliente. Por ejem-
plo, un software para wikis es un sevidor de aplicacio-
nes que permite a los usuarios desarrollar contenido di-
námico ensamblado a partir de artículos. Las Wikis ge-
neran HTML, CSS, Java, y Javascript los cuales son
interpretados por un navegador web.
11.2.4 Ejecución simultánea
Muchos programas pueden correr simultáneamente en
la misma computadora, a lo cual se le conoce como
multitarea y puede lograrse a través de mecanismos de
software o de hardware. Los sistemas operativos mo-
dernos pueden correr varios programas a través del
planificador de procesos — un mecanismo de software
para conmutar con frecuencia la cantidad de procesos del
procesador de modo que los usuarios puedan interactuar
con cada programa mientras estos están corriendo.[11]
11.6. BIBLIOGRAFÍA 41
También se puede lograr la multitarea por medio del
hardware; las computadoras modernas que usan varios
procesadores o procesadores con varios núcleos pueden
correr muchos programas a la vez.[12]
11.3 Categorías funcionales
Los programas se pueden categorizar según líneas funcio-
nales. Estas categorías funcionales son software de sis-
tema y software de aplicación. El software de sistema
incluye al sistema operativo el cual acopla el hardware
con el software de aplicación.[13]
El propósito del siste-
ma operativo es proveer un ambiente en el cual el soft-
ware de aplicación se ejecuta de una manera conveniente
y eficiente.[13]
Además del sistema operativo, el softwa-
re de sistema incluye programas utilitarios que ayudan a
manejar y configurar la computadora. Si un programa no
es software de sistema entonces es software de aplicación.
El middleware también es un software de aplicación que
acopla el software de sistema con la interfaz de usuario.
También son software de aplicación los programas utili-
tarios que ayudan a los usuarios a resolver problemas de
aplicaciones, como por ejemplo la necesidad de ordena-
miento.
11.4 Véase también
• Algoritmo para la relación entre los programas in-
formáticos y algoritmos
• Estructura de datos
• Archivo cabra para un tipo específico de programa
informático utilizado solo para liberar y estudiar los
efectos de virus informáticos en los sistemas físicos
y virtuales
• Inteligencia artificial
• Sistema multi-agente
• Aplicaciones informáticas
11.5 Referencias
[1] Stair, Ralph M., et al. (2003). Principles of Information
Systems, Sixth Edition (en inglés). Thomson Learning, Inc.
p. 132. ISBN 0-619-06489-7.
[2] Silberschatz, Abraham (1994). Operating System Con-
cepts, Fourth Edition (en inglés). Addison-Wesley. p. 58.
ISBN 0-201-50480-4.
[3] «Algorithms and Computer Programming» (en inglés).
Consultado el 8 de setiembre de 2014.
[4] Wilson, Leslie B. (1993). Comparative Programming Lan-
guages, Second Edition (en inglés). Addison-Wesley. p. 75.
ISBN 0-201-56885-3.
[5] Wilson, Leslie B. (1993). Comparative Programming Lan-
guages, Second Edition (en inglés). Addison-Wesley. p.
213. ISBN 0-201-56885-3.
[6] Wilson, Leslie B. (1993). Comparative Programming Lan-
guages, Second Edition (en inglés). Addison-Wesley. p.
244. ISBN 0-201-56885-3.
[7] «What is a Compiler?» (en inglés). Consultado el 10 de
enero de 2012.
[8] Silberschatz, Abraham (1994). Operating System Con-
cepts, Fourth Edition (en inglés). Addison-Wesley. p. 30.
ISBN 0-201-50480-4.
[9] Tanenbaum, Andrew S. (1990). Structured Computer Or-
ganization, Third Edition. Prentice Hall. p. 11. ISBN 0-
13-854662-2. (en inglés).
[10] Silberschatz, Abraham (1994). Operating System Con-
cepts, Fourth Edition (en inglés). Addison-Wesley. p. 6.
ISBN 0-201-50480-4.
[11] Silberschatz, Abraham (1994). Operating System Con-
cepts, Fourth Edition (en inglés). Addison-Wesley. p. 100.
ISBN 0-201-50480-4.
[12] Akhter, Shameem (2006). Multi-Core Programming. Ri-
chard Bowles (Intel Press). pp. 11–13. ISBN 0-9764832-
4-6. (en inglés).
[13] Silberschatz, Abraham (1994). Operating System Con-
cepts, Fourth Edition (en inglés). Addison-Wesley. p. 1.
ISBN 0-201-50480-4.
11.6 Bibliografía
• Knuth, Donald E. (1997). The Art of Computer Pro-
gramming, Volume 1, 3rd Edition (en inglés). Bos-
ton: Addison-Wesley. ISBN 0-201-89683-4.
• Knuth, Donald E. (1997). The Art of Computer Pro-
gramming, Volume 2, 3rd Edition (en inglés). Bos-
ton: Addison-Wesley. ISBN 0-201-89684-2.
• Knuth, Donald E. (1997). The Art of Computer Pro-
gramming, Volume 3, 3rd Edition (en inglés). Bos-
ton: Addison-Wesley. ISBN 0-201-89685-0.
11.7 Enlaces externos
• Definición de “Programa” en Webopedia (en inglés)
• Definición de “Computer Program” en dictio-
nary.com (en inglés)
42 CAPÍTULO 11. PROGRAMA INFORMÁTICO
• Esta obra deriva de la traducción total de Computer
program de Wikipedia en inglés, concretamente
de esta versión, publicada por sus editores ba-
jo la Licencia de documentación libre de GNU
y la Licencia Creative Commons Atribución-
CompartirIgual 3.0 Unported.
11.8. TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES 43
11.8 Text and image sources, contributors, and licenses
11.8.1 Text
• Computadora Fuente: http://es.wikipedia.org/wiki/Computadora?oldid=81730079 Colaboradores: PACO, Joseaperez, Srtxg, Oblongo,
Moriel, Sauron, JorgeGG, Digital-h, Pieter, AlexAlonso, Mxn, Wesisnay, Lourdes Cardenal, Hashar, ManuelGR, Julie, Robbot, Angus,
Mdiagom, Vivero, Zwobot, Comae, Paz.ar, Drjackzon, Rosarino, Dodo, Pybalo, Wikilibrarian~eswiki, Felipe.bachomo, Sms, Avm, Tos-
tadora, Tano4595, Jarfil, Robotito, Enric Naval, Carlos Quesada~eswiki, Dianai, Triebjlr, Pablomdo, Cinabrium, Porao, Trylks, Evi-
llan~eswiki, 142857, Vizcarra~eswiki, Ecemaml, Kordas, Padeleti, Elsenyor, Niqueco, Renabot, Richy, FAR, Supersouissi, Javierme,
Reignerok, Digigalos, Taragui, Sonett72~eswiki, Boticario, Deleatur, Soulreaper, Petronas, Orgullomoore, Pencho15, Airunp, JMPerez,
Edub, Klemen Kocjancic, Yrithinnd, Taichi, Emijrp, Rembiapo pohyiete (bot), Gussisaurio, Wikiseldon, Magister Mathematicae, Kokoo,
RedTony, Ericbaez, Goofys, Orgullobot~eswiki, RobotQuistnix, Byj2000, Platonides, Itnas19, Veltys, Alhen, Superzerocool, Chobot, San-
cebau, Deprieto, Yrbot, Amadís, BOT-Superzerocool, Dagavi, Oscar ., FlaBot, Varano, Vitamine, .Sergio, Dangarcia, Mortadelo2005,
Juan.res~eswiki, Museo8bits, Olea, GermanX, Lin linao, Equi, Zam, Willtron, Unaiaia, Armin76, Gaijin, The Photographer, Jesuja, Tiger-
fenix, Santiperez, Txo, Leitzaran, HECTOR ARTURO AZUZ SANCHEZ, Banfield, CHV, JanoMasoneria, Milestones, José., Maldoror,
Er Komandante, Tomatejc, Jarke, EOZyo, Siabef, Folkvanger, Makahaxi, The worst user, Tafol, Zand, BOTpolicia, Reynaldo Villegas Pe-
ña, Alfa989, Gizmo II, CEM-bot, Jorgelrm, Gabriel Acquistapace, Laura Fiorucci, Pinar~eswiki, Heavyrock, Nagul, Roblespepe, Ignacio
Icke, Durero, Jjvaca, Mrjoui, Pacostein, Baiji, Roberpl, Rastrojo, Dantadd, Antur, Patori, Willicab, Eledwin01, Jjafjjaf, Gafotas, Progra-
mador, Dorieo, Montgomery, FrancoGG, Resped, Thijs!bot, Persona~eswiki, Xoacas, Frankcu, Ricardoramirezj, Tortillovsky, Mahadeva,
Bot que revierte, Escarbot, Kommodin, RoyFocker, Ángel Luis Alfaro, Albireo3000, Will vm, PhJ, Ranf, Botones, Cratón, Isha, Jdvilla-
lobos, Kenbill, Tarantino, Chuck es dios, Hanjin, Dogor, Góngora, Artaris, JAnDbot, Darolu, Jugones55, Casamanita, VanKleinen, Kved,
DerHexer, Praedos, Mansoncc, Satin, Marinna, Muro de Aguas, Xavigivax, CommonsDelinker, TXiKiBoT, FeKuLa, Cronos x, Jdiezchica,
Bot-Schafter, Gacq, Humberto, Netito777, HAMM, Rodgarcia, Camilogalactico, Amanuense, Pedro Nonualco, Chabbot, MotherForker,
Idioma-bot, Qoan, Pólux, BL, Jmvkrecords, Developer, Jesus 2003 18 x, Vtornet, Manuel Trujillo Berges, Jtico, Kzman, Avsurrutia, Biaso-
li, Bucephala, AlnoktaBOT, Yio, Cinevoro, Exitocoastal, VolkovBot, Jurock, Snakeyes, Technopat, C'est moi, Queninosta, Penarc, Chixpy,
Libertad y Saber, Penguino, Josell2, Matdrodes, Ghsus, Fernando Estel, Elabra sanchez, Synthebot, KLosma, BlackBeast, Shooke, Lucien
leGrey, Netmaster123, Vatelys, AlleborgoBot, Zaca83, Vladimir138, Chicano~eswiki, Muro Bot, Edmenb, Komputisto, Bucho, Racso,
YonaBot, BotMultichill, Gerakibot, SieBot, Mushii, Ctrl Z, Naitsirk, Loveless, Macarrones, Rimac, El duende alegre, Carmin, Pompilio
Zigrino, Cobalttempest, OLM, Rigenea, Chrihern, Drinibot, Rodolfoap, Bigsus-bot, BOTarate, Wiljoel, STBot~eswiki, Mel 23, Manwë,
Pascow, Correogsk, Chino-akd, Garber, Greek, Elmascapodetodos, BuenaGente, Mazzuccoxp, Aleposta, Mafores, PipepBot, Chico512,
Ivanics, Tirithel, Mutari, Locos epraix, robot, Superzambo, Montehermoso-spain, Javierito92, Marcecoro, HUB, Antón Francho,
Rodrigofeu, Nicop, DragonBot, JOKblogger, McMalamute, Eduardosalg, Cristinita19, P4K1T0, John.007, Qwertymith, EdgarGSX, Leon-
polanco, Pan con queso, Alejandroml, Alejandrocaro35, LuisArmandoRasteletti, Furti, Cayosama, Pene255, Poco a poco, BetoCG, Lloyd-
02, Rαge, Açipni-Lovrij, Nepenthes, Rodog, Hierro duro, Porromaligno10, UA31, Waldner~eswiki, SergioN, MARC912374, AVBOT,
David0811, Jorghex, LucienBOT, A ver, Louperibot, Hemingway10, Angel GN, Ponchoperez, Joan231, Carlos A. Baez, Diegusjaimes,
Davidgutierrezalvarez, MelancholieBot, Linfocito B, Rezagos, Manuelito.angelito, Danitza iveth, Miguelpab, CarsracBot, JohnManuel,
Parra christopher, Arjuno3, Lucas dicci, Andreasmperu, Dalton2, Ramon00, ASPARTAME, Jotterbot, Bucle, Ixfd64, Tauro1990, Elec-
trodan, Dangelin5, Joseagrc, Yodigo, Barteik, Koj, Oskar105, Isah213, Juanangeles55, Hampcky, Shekatsu8er, Oodrap, Vivaelcelta, Nixón,
ArthurBot, Diogeneselcinico42, ChristianH, Manuelt15, Xqbot, Simeón el Loco, Jkbw, SassoBot, Dreitmen, Jandres95, Maron siglos15,
Enrique Consultas, FrescoBot, Ricardogpn, Jvv110687, Lauragaribaldi, Olga Atzimba, Igna, Javier Castaneda, MauritsBot, Kroci, Tobe-
Bot, PDD20, Zenapau, Vubo, DixonDBot, Andersonpana31, Abece, Lungo, Wikipedico wikipedico, Fitoschido, Clesmery, TorQue Astur,
Steveen777, Jembot, PatruBOT, Beatriz taboas, Cesar Eduardo Ballesteros Aguirre, KamikazeBot, Xitlalimons, Almiux2009, Angelito7,
TjBot, Ripchip Bot, Olivares86, Tarawa1943, Jorge c2010, Foundling, Wikiléptico, Axvolution, P. S. F. Freitas, Velual, EmausBot, Savh,
AVIADOR, ZéroBot, HRoestBot, ChessBOT, Sergio Andres Segovia, ChuispastonBot, Cedecomsa, MadriCR, WikitanvirBot, Mjbmrbot,
Movses-bot, Astronomo solar, Betostw, Metrónomo, El magio12, MerlIwBot, KLBot2, Vagobot, Sebrev, MetroBot, Invadibot, Nernix1,
Acratta, LlamaAl, Santga, Akdkiller, Jpyamamoto09, MaKiNeoH, Legobot, Addbot, Balles2601, Nación del fuego100, TheDarkGosht,
Toniperis, Rsniaza, Sintaxis Sintáctico, JacobRodrigues, Ffranciscovegav, Minasadaft, Ivan giovani silva palafox, Guayo1300, Josesuazoo,
Gavillas, UMIdani, BY THE, Gddgd, Timohap, MrCharro, Jarould, Crystallizedcarbon, Pipemancini, Boloni14, Chovichovy, Luis felipe
martinez sanchez, Dfcordoba, Pinkilurulu, Domyalatorre, Maribel001, BenjaBot y Anónimos: 1133
• Ciencias de la información (tecnología) Fuente: http://es.wikipedia.org/wiki/Ciencias%20de%20la%20informaci%C3%B3n%
20(tecnolog%C3%ADa)?oldid=80271027 Colaboradores: Trylks, Eloy, Tamorlan, CEM-bot, Davius, Ángel Luis Alfaro, Serg!o,
NaBUru38, Technopat, Kavor, Ruud Koot, SuperBraulio13, Canyq, Waeswaes, Grillitus, El Ayudante, ConnieGB y Anónimos: 9
• Lenguaje de programación Fuente: http://es.wikipedia.org/wiki/Lenguaje%20de%20programaci%C3%B3n?oldid=81986369 Colabo-
radores: AstroNomo, Carlita~eswiki, Nnss, Joseaperez, Moriel, Sauron, JorgeGG, ManuelGR, Julie, Angus, Rumpelstiltskin, Achury, San-
bec, Zwobot, Javier Carro, Scott MacLean, MiguelRdz, Dodo, Triku, Ascánder, Avm, Rsg, HHM, Cookie, Tostadora, Elwikipedista, Da-
nakil~eswiki, Murphy era un optimista, Jsanchezes, Jarfil, Elproferoman, Melocoton, Kalcetin, Porao, Trylks, Almorca, Suruena, Balderai,
Dat, Niqueco, ZackBsAs, Ilario, LeonardoRob0t, Digigalos, Zeioth, Soulreaper, AlfonsoERomero, Airunp, JMPerez, Edub, Taichi, Rem-
biapo pohyiete (bot), Genba, Magister Mathematicae, Aadrover, Orgullobot~eswiki, RobotQuistnix, Gcsantiago, Platonides, Unf, LarA,
Alhen, Superzerocool, Chobot, Yrbot, BOT-Superzerocool, Oscar ., Martincarr, Vitamine, Cesarsorm, Wiki-Bot, Icvav, GermanX, Aalva-
radoH, Indu~eswiki, KnightRider, Jesuja, Tigerfenix, Santiperez, PabloBD, Banfield, Otermin, Nowadays, Er Komandante, Spc, Tomatejc,
Balix, Rbonvall, Jorgechp, Juanjo64, BOTpolicia, Qwertyytrewqqwerty, Chfiguer, CEM-bot, Jorgelrm, Krli2s, Spazer, Alex15090, Xemuj,
Ignacio Icke, Retama, Baiji, Ezequiel3E, Osepu, Roberpl, JoRgE-1987, Eamezaga, Antur, Mr. Moonlight, FrancoGG, Fsd141, Juank8041,
Alvaro qc, Srengel, Cansado, Mahadeva, Rata blanca, Diosa, Escarbot, RoyFocker, Eduiba, IrwinSantos, Will vm, Tintinando, Botones, Cra-
tón, Isha, Arcibel, Mpeinadopa, JAnDbot, Thormaster, Jugones55, BelegDraug, Diego.souto, Kved, TitoPeru, Mansoncc, BetBot~eswiki,
Xavigivax, Danielantonionunez, Bot-Schafter, Elisardojm, Humberto, Netito777, Amanuense, Bedwyr, Idioma-bot, Pólux, Sebado, Bu-
cephala, AlnoktaBOT, Dusan, Cinevoro, VolkovBot, Carola-zzz, Snakeyes, Technopat, Galandil, Queninosta, Aliamondano, Pejeyo, Mat-
drodes, Elabra sanchez, Synthebot, House, DJ Nietzsche, Gorpik, Lucien leGrey, AlleborgoBot, Gmarinp, IIM 78, Muro Bot, Edmenb,
J.M.Domingo, Komputisto, Bucho, SieBot, Mushii, Danielba894, Carlos Zeas, Cobalttempest, Rigenea, Hompis, Drinibot, Bigsus-bot,
IsmaelLuceno, Mel 23, Manwë, Correogsk, Greek, Joseromerogc, BuenaGente, Mafores, Cam367, Tirithel, Jarisleif, Javierito92, HUB,
FCPB, Eduardosalg, Edgarchan, Leonpolanco, Pan con queso, Alecs.bot, LordT, Descansatore, Petruss, Poco a poco, Juan Mayordomo,
Darkicebot, Rαge, MADAFACK, Frei sein, Raulshc, Açipni-Lovrij, Majin boo, Camilo, UA31, Inakivk, Esterdelakpaz, CharlesKnight,
AVBOT, Swatnio, DayL6, David0811, J.delanoy, MarcoAurelio, JyQ, Ezarate, Diegusjaimes, MelancholieBot, Linfocito B, Sebasweee,
44 CAPÍTULO 11. PROGRAMA INFORMÁTICO
Arjuno3, Andreasmperu, Luckas-bot, MystBot, Bob A, Roinpa, Jotterbot, Sappler, Akhran, Vic Fede, Barteik, Billinghurst, Vandal Crus-
her, Julio Cardmat, XZeroBot, ArthurBot, Argentinoo, Jefrcast, SuperBraulio13, Ortisa, Manuelt15, Xqbot, Jkbw, SassoBot, Dreitmen,
Ricardogpn, Igna, Torrente, Adryitan, Botarel, MauritsBot, Googolplanck, Hprmedina, TobeBot, Execoot~eswiki, Palita1880, Halfdrag,
Vubo, YSCO, PatruBOT, Ganímedes, Angelito7, Mr.Ajedrez, Jose1080i, Humbefa, Tarawa1943, Jorge c2010, GrouchoBot, Cesarintel,
Miss Manzana, Jose1100000, Edslov, EmausBot, Savh, AVIADOR, Ingenieros instructivos, HRoestBot, Allforrous, Sergio Andres Sego-
via, Chope777, Rubpe19, Eroyuela, ChuispastonBot, MadriCR, Waka Waka, Cordwainer, Lcsrns, Antonorsi, Valthern, Edc.Edc, Ismaell,
Jicapter, Sebrev, MetroBot, Sansgumen, Mascorria, Teclis jma, Gusama Romero, Nernix1, Acratta, Johnbot, Harpagornis, LlamaAl, Helmy
oved, Erandly, Flashlack, Cyrax, Napier, Ralgisbot, Syum90, Fabrizotus, BLACK M0NST3R, Juanitoalcachofados, Addbot, Shinigamisa-
jayin, Balles2601, Killtas, Patoogalvan, Davidpaisa04, DarkBlueZV, Equiz yolo swaw, Jarould, Matiia, Egis57, Geekisthebest1, Ximenacs
y Anónimos: 809
• Algoritmo Fuente: http://es.wikipedia.org/wiki/Algoritmo?oldid=81963760 Colaboradores: Llull~eswiki, Pit~eswiki, Sabbut, Moriel, Sau-
ron, JorgeGG, Lourdes Cardenal, ManuelGR, Julie, Angus, Vivero, Riviera, Rosarino, Dodo, Ejmeza, Crescent Moon, Triku, Sms, Rsg,
Tostadora, Elwikipedista, Tano4595, Jsanchezes, Ríos-Ortega, JAAC, Jecanre, Cinabrium, Schummy, Huhsunqu, Balderai, Ecemaml, Re-
nabot, FAR, Ictlogist, Boticario, Soulreaper, Orgullomoore, AlfonsoERomero, Airunp, JMPerez, Edub, Yrithinnd, Taichi, Emijrp, Rem-
biapo pohyiete (bot), Caiser, Magister Mathematicae, RobotQuistnix, Alhen, Superzerocool, Chobot, Dromero, Sancebau, Yrbot, Amadís,
FlaBot, Vitamine, .Sergio, YurikBot, Mortadelo2005, GermanX, Zam, Willtron, KnightRider, The Photographer, YoaR, Gothmog, No sé
qué nick poner, Carutsu, C-3POrao, Jesuja, Banfield, Maldoror, Er Komandante, Camima, Haitike, KocjoBot~eswiki, Tomatejc, Jarke,
Paintman, Rbonvall, Kn, Aleator, Jstitch, BOTpolicia, Gizmo II, CEM-bot, Jorgeu, Jorgelrm, Laura Fiorucci, Kojie, -jem-, Alexav8, Ignacio
Icke, Efegé, Retama, AlphaWiki~eswiki, Baiji, Bot~eswiki, Antur, Dorieo, Ingenioso Hidalgo, Fsd141, AlbertMA, Thijs!bot, Xxim, Alvaro
qc, Escarbot, Yeza, Zupez zeta, Drake 81, RoyFocker, Ninovolador, MorZilla, Cratón, Isha, Dogor, Gusgus, Obueno, JAnDbot, Jugones55,
JuanRodríguez, Kved, DerHexer, Lecuona, Mansoncc, Muro de Aguas, Xavigivax, TXiKiBoT, S3v3r-1, Elisardojm, Humberto, Netito777,
Sophie kowalsky, AS990, ZrzlKing, Chabbot, Pólux, Bucephala, AchedDamiman, VolkovBot, Snakeyes, Technopat, Queninosta, Rays-
torm, Libertad y Saber, Matdrodes, Elabra sanchez, Synthebot, DJ Nietzsche, BlackBeast, Shooke, AlleborgoBot, Muro Bot, Peregring-lk,
Clarad, Komputisto, MiguelAngel fotografo, SieBot, Aitorzubiaurre, Danielba894, Ctrl Z, Francisco Mochis, Carmin, Rigenea, Drinibot,
CASF, BOTarate, Arlm1, Fide07, STBot~eswiki, Mel 23, Guillervf91, Manwë, Fegc77, Greek, H3r3dia, BuenaGente, Qix~eswiki, Relleu,
PipepBot, Fadesga, Chuchot, Tirithel, Mutari, XalD, robot, Jarisleif, Javierito92, HUB, PeruProfe, Farisori, McMalamute, Estira-
bot, Eduardosalg, Veon, Leonpolanco, Pan con queso, Mar del Sur, Alejandrocaro35, Botito777, Petruss, Alexbot, Darkicebot, Valentin
estevanez navarro, RoyFokker, Raulshc, Açipni-Lovrij, SilvonenBot, Camilo, UA31, Ucevista, AVBOT, David0811, Flakinho, Nocturno-
gatuno, MastiBot, Pedrito suarez, Angel GN, MarcoAurelio, Speedplus, Ezarate, Diegusjaimes, Jjflorescueto, Arjuno3, Andreasmperu,
Luckas-bot, Virgi, Ptbotgourou, Jotterbot, Vic Fede, Dangelin5, Eduman~eswiki, Nixón, DSisyphBot, XZeroBot, ArthurBot, Ruy Pu-
gliesi, Lcpousa, SuperBraulio13, M.heda, Xqbot, Jkbw, GhalyBot, Junior1209, Pedrovicenterosero, Calitb, Albertochoa, Igna, Torrente,
Botarel, BenzolBot, Heynry1, Gusbelluwiki, Jhoelito14, TobeBot, Adrianantoniors, Imperioonepiece, Halfdrag, Aquiel, Mipataentutrasero,
Wikielwikingo, Hantartico, KamikazeBot, , Abel406, TjBot, Alph Bot, Humbefa, Irvinopuma, Carlo el calvo, Shining.Star, Foundling,
GrouchoBot, Xxxmagicmanxxx, Edslov, EmausBot, Savh, HRoestBot, Sergio Andres Segovia, Macrocoliset, Emiduronte, ChuispastonBot,
MadriCR, Waka Waka, Xpress500, Mjbmrbot, Miguel hdez, Ksarasola, Metrónomo, Antonorsi, MerlIwBot, Papaplus, Renly, ClausxD,
Arthur 'Two Sheds’ Jackson, Sebrev, Ginés90, Kotas, MetroBot, Henry bedon, Gusama Romero, Acratta, Metilisopropilisergamida, Vetra-
nio, Elvisor, Sandovaltk10, Helmy oved, Syum90, Legobot, Eyetheunlord, Balles2601, ConnieGB, Angelrafa00, Jarould, Matiia, Egis57,
Crystallizedcarbon, AlexGaitan, Deforetop6, Yholo, Andres477, Sapristi1000, CarlosAR2000, Benito Álvaro Cifuentes, Lalito312000,
Benigno Jimenez Garay, Holaxddddd, Joltenick y Anónimos: 789
• Algoritmo determinista Fuente: http://es.wikipedia.org/wiki/Algoritmo%20determinista?oldid=71508940 Colaboradores: Riviera,
Tano4595, Chobot, Yrbot, BOTijo, R0MAN0, CEM-bot, Nagul, Martínhache, Fsd141, Thijs!bot, Muro Bot, SieBot, DragonBot, DumZi-
BoT, Luckas-bot, MystBot, SassoBot, JViejo, WikitanvirBot, KLBot2, Acratta, Elvisor, JacobRodrigues y Anónimos: 4
• Estructura de datos Fuente: http://es.wikipedia.org/wiki/Estructura%20de%20datos?oldid=81150159 Colaboradores: Edulix, Soniautn,
Sabbut, Moriel, Sauron, Julie, Zwobot, Comae, Dodo, Triku, Fortran~eswiki, Sms, Rsg, Murphy era un optimista, Jsanchezes, LPR, Porao,
Alexan, Emijrp, Rembiapo pohyiete (bot), RobotQuistnix, Platonides, Chobot, Yrbot, BOTijo, YurikBot, Icvav, KnightRider, Jesuja, Txo,
Götz, Maldoror, Chlewbot, Tomatejc, Fercufer, Laura Fiorucci, Alexav8, Fsd141, Thijs!bot, Rasilga, Miguelo on the road, TXiKiBoT, Juan
renombrado, Hidoy kukyo, Danthux, Humberto, Developer, Biasoli, AlnoktaBOT, VolkovBot, Matdrodes, YonaBot, BotMultichill, SieBot,
Loveless, Furti, Alexbot, Açipni-Lovrij, SilvonenBot, Rrupo, AVBOT, David0811, MastiBot, MarcoAurelio, Diegusjaimes, DumZiBoT,
Luckas-bot, Yonidebot, ArthurBot, Alexandravargas, SuperBraulio13, Ortisa, Xqbot, Jkbw, Asfarer, Ricardogpn, Botarel, Aquiel, Patru-
BOT, Dinamik-bot, Crg 85, EmausBot, ZéroBot, WikitanvirBot, Manubot, Xerox 5B, Rezabot, MerlIwBot, Jetjanoli, V.aguado, Seasz,
Addbot, DarkBlueZV y Anónimos: 79
• Cola (informática) Fuente: http://es.wikipedia.org/wiki/Cola%20(inform%C3%A1tica)?oldid=81430190 Colaboradores: Moriel, Jor-
geGG, Robbot, Sms, Emijrp, BOTijo, The Photographer, Jesuja, Eduardo Lima, Jarke, CEM-bot, Thijs!bot, Diosa, Isha, JAnDbot, Pólux,
AlnoktaBOT, Technopat, BotMultichill, SieBot, Ctrl Z, El3ctron, Loveless, BOTarate, Nubecosmica, Ken123BOT, WikiBotas, Tirithel,
Kikobot, Farisori, Eduardosalg, Qwertymith, Jduarte, Poco a poco, Mithy, Alexbot, SilvonenBot, MastiBot, Diegusjaimes, Arjuno3, Jot-
terbot, DSisyphBot, Amadeupons, Alvaromedina, Xqbot, Jkbw, PabloRCR, Josemgm89, Igna, Panderine!, Hprmedina, KamikazeBot,
EmausBot, Africanus, Waka Waka, DOOM17, Syum90, Ocaroline, Addbot, Miguel940829, DarkBlueZV, Moispi y Anónimos: 72
• Tipo de dato abstracto Fuente: http://es.wikipedia.org/wiki/Tipo%20de%20dato%20abstracto?oldid=80031514 Colaboradores: Angus,
Zwobot, Comae, RolanRBD, Ascánder, Sms, Avm, Elwikipedista, Beagle~eswiki, WhisKiTo, Rembiapo pohyiete (bot), RobotQuistnix,
Platonides, Jcgarcianaranjo, YurikBot, Mortadelo2005, GermanX, Equi, KnightRider, Eskimbot, Maldoror, Leonardocaballero, CEM-
bot, RaulFraileBeneyto, Anicholo~eswiki, Karshan, Thijs!bot, Alvaro qc, Javierrami, Bot que revierte, JAnDbot, TXiKiBoT, Netito777,
Rei-bot, Idioma-bot, Fremen, Gomesbascoy, Technopat, Fernando Estel, Mjollnir1984, BOTarate, Tesi1700, Ken123BOT, Tirithel, Mi-
guel, Eduardosalg, Juan Mayordomo, UA31, AVBOT, Santiagobas, DumZiBoT, Diádoco, ArthurBot, RedBot, Dinamik-bot, Ebrambot,
ChuispastonBot, MadriCR, Pablombg, KLBot2, Robotsfuture, Bambadee, Fenixchava, JYBot, Addbot y Anónimos: 45
• Vector (informática) Fuente: http://es.wikipedia.org/wiki/Vector%20(inform%C3%A1tica)?oldid=81151693 Colaboradores: Juancri,
Pino, Moriel, Sauron, Robbot, Dodo, Crescent Moon, Tano4595, Toad32767, Boticario, Taichi, LeCire, RobotQuistnix, Caiserbot, Dro-
mero, Yrbot, BOTijo, YurikBot, GermanX, KnightRider, Jesuja, Götz, Maldoror, Chlewbot, Tomatejc, CEM-bot, Jorgelrm, JMCC1,
Especiales, Baiji, Rosarinagazo, Clokr, IrwinSantos, JAnDbot, Spa karmona, LeinaD natipaC, TXiKiBoT, Kandorf, Netito777, Biasoli,
Cinevoro, VolkovBot, Matdrodes, BlackBeast, Gmarinp, Muro Bot, BotMultichill, SieBot, Cholga~eswiki, Veon, Alejandrocaro35, Poco
a poco, Juan Mayordomo, Darkicebot, SilvonenBot, Rrupo, Albambot, AVBOT, MastiBot, Diegusjaimes, DumZiBoT, CarsracBot, Ja-
vu61, Luckas-bot, XZeroBot, SuperBraulio13, Xqbot, Jkbw, A. Guizar, Hprmedina, CVBOT, Yago AB, Dinamik-bot, Fran89, Pke93,
11.8. TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES 45
EmausBot, Savh, HRoestBot, Sergio Andres Segovia, Grillitus, MerlIwBot, Helmy oved, Makecat-bot, 2rombos, Miguel2706, Addbot,
DonRulasRules, Jarould, Benigno Jimenez Garay y Anónimos: 116
• Pila (informática) Fuente: http://es.wikipedia.org/wiki/Pila%20(inform%C3%A1tica)?oldid=81315564 Colaboradores: Robbot, Vivero,
Fortran~eswiki, Sms, Richy, Boticario, Emijrp, RobotQuistnix, FlaBot, BOTijo, YurikBot, GermanX, The Photographer, Jesuja, Banfi-
eld, Fernd, Chlewbot, Rbonvall, Kn, BOTpolicia, CEM-bot, Laura Fiorucci, Rjelves, Thijs!bot, JoaquinFerrero, Isha, TXiKiBoT, Sirpup-
pet, Pólux, Sebado, Biasoli, AchedDamiman, AlnoktaBOT, Cinevoro, Technopat, Matdrodes, Shooke, BotMultichill, SieBot, Loveless,
Greek, Farisori, Botito777, Martaka, Sire, Poco a poco, Juan Mayordomo, BotSottile, Shalbat, AVBOT, Ezarate, Diegusjaimes, DumZi-
BoT, MelancholieBot, Andreasmperu, Luckas-bot, MystBot, Nallimbot, Ptbotgourou, LyingB, GCaracuel, Xqbot, Jkbw, Ealmagro, Botarel,
D'ohBot, Gbduende, KamikazeBot, Angelito7, Foundling, EmausBot, Savh, ZéroBot, HRoestBot, David f.1993, ChuispastonBot, Phaetton,
WikitanvirBot, MerlIwBot, Harpagornis, Creosota, Helmy oved, Makecat-bot, Vengadora, Legobot, Ocaroline, Addbot, JacobRodrigues,
DarkBlueZV, Moispi, David Condrey y Anónimos: 98
• Programa informático Fuente: http://es.wikipedia.org/wiki/Programa%20inform%C3%A1tico?oldid=82060404 Colaboradores: Ejme-
za, Taichi, Magister Mathematicae, Chobot, Vitamine, GermanX, Gaijin, The Photographer, Banfield, CEM-bot, Jorgelrm, Nagul, Baiji,
Jgomo3, Dorieo, Escarbot, RoyFocker, Cratón, Isha, JAnDbot, Jugones55, Gsrdzl, CommonsDelinker, VityUvieu, Gacq, Humberto, Ama-
nuense, Idioma-bot, Pólux, Biasoli, Cinevoro, VolkovBot, Technopat, Queninosta, Matdrodes, Elabra sanchez, Shooke, Lucien leGrey,
Gerakibot, SieBot, PaintBot, Rigenea, Bigsus-bot, BOTarate, Mel 23, Tirithel, Javierito92, HUB, Estirabot, Eduardosalg, Botellín, Leonpo-
lanco, Alejandrocaro35, Botito777, Petruss, Açipni-Lovrij, UA31, SergioN, MARC912374, AVBOT, David0811, Angel GN, SubSeven-
MoRpHeEuS, MarcoAurelio, NjardarBot, Diegusjaimes, Mikiguti, CarsracBot, Arjuno3, Saloca, Luckas-bot, Spirit-Black-Wikipedista,
Roinpa, Dangelin5, Axel.axel, Nixón, ArthurBot, SuperBraulio13, Xqbot, Jkbw, Igna, Botarel, D'ohBot, BOTirithel, AnselmiJuan, Pa-
truBOT, KamikazeBot, Rudol0075, Foundling, EmausBot, Bachi 2805, Savh, ZéroBot, HRoestBot, Grillitus, Rubpe19, Jcaraballo, Ma-
driCR, AStarBot, MerlIwBot, Vagobot, MetroBot, BiTAlejandro, Elvisor, Helmy oved, Makecat-bot, Addbot, Balles2601, Amautita12,
AVIADOR-bot, Jarould, Kevin15jdr, Beromawiki y Anónimos: 169
11.8.2 Images
• Archivo:ALU_symbol.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/8/82/ALU_symbol.svg Licencia: CC-BY-SA-3.0
Colaboradores: Este gráfico vectorial fue creado con Inkscape. Artista original: en:User:Cburnett
• Archivo:AlgoritmoRaiz.png Fuente: http://upload.wikimedia.org/wikipedia/commons/2/26/AlgoritmoRaiz.png Licencia: CC-BY-SA-
3.0 Colaboradores: Trabajo propio, hecho con OpenOffice.org Draw Artista original: Kn
• Archivo:Arquitectura_von_Neumann.png Fuente: http://upload.wikimedia.org/wikipedia/commons/b/bd/Arquitectura_von_
Neumann.png Licencia: CC-BY-SA-3.0 Colaboradores: ? Artista original: ?
• Archivo:Array1.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/3/3f/Array1.svg Licencia: Public domain Colaboradores: ?
Artista original: ?
• Archivo:Check_mark.png Fuente: http://upload.wikimedia.org/wikipedia/commons/f/f0/Check_mark.png Licencia: ? Colaboradores:
Wikipedia Artista original: Wikipedia
• Archivo:Classes_and_Methods.png Fuente: http://upload.wikimedia.org/wikipedia/commons/d/d0/Classes_and_Methods.png Licen-
cia: CC BY-SA 3.0 Colaboradores: Using SublimeText Artista original: Bobbygammill
• Archivo:CodeCmmt002.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/7/75/CodeCmmt002.svg Licencia: CC BY 2.5 Co-
laboradores: Transferido desde en.wikipedia a Commons.28041964 Artista original: The original uploader was Dreftymac de Wikipedia
en inglés
• Archivo:Cola.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/b/bb/Cola.svg Licencia: CC BY-SA 3.0 Colaboradores:
Image:Data_Queue.svg by User:Vegpuff Artista original: User:Vegpuff,User:Ocaroline User:Boivie
• Archivo:ColaProg.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/5/5c/ColaProg.JPG Licencia: CC-BY-SA-3.0 Colabo-
radores: Trabajo propio Artista original: Jduarte
• Archivo:Commons-emblem-copyedit.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/e/e8/Commons-emblem-copyedit.
svg Licencia: CC BY-SA 3.0 Colaboradores:
• File:Gnome-emblem-important.svg Artista original: GNOME icon artists, Fitoschido
• Archivo:Commons-emblem-question_book_orange.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/1/1f/
Commons-emblem-question_book_orange.svg Licencia: CC BY-SA 3.0 Colaboradores: <a href='//commons.wikimedia.org/
wiki/File:Commons-emblem-issue.svg' class='image'><img alt='Commons-emblem-issue.svg' src='//upload.wikimedia.org/
wikipedia/commons/thumb/b/bc/Commons-emblem-issue.svg/25px-Commons-emblem-issue.svg.png' width='25' height='25'
srcset='//upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Commons-emblem-issue.svg/38px-Commons-emblem-issue.svg.png
1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Commons-emblem-issue.svg/50px-Commons-emblem-issue.svg.png 2x'
data-file-width='48' data-file-height='48' /></a> + <a href='//commons.wikimedia.org/wiki/File:Question_book.svg' class='image'><img
alt='Question book.svg' src='//upload.wikimedia.org/wikipedia/commons/thumb/9/97/Question_book.svg/25px-Question_book.svg.png'
width='25' height='20' srcset='//upload.wikimedia.org/wikipedia/commons/thumb/9/97/Question_book.svg/38px-Question_book.svg.
png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/9/97/Question_book.svg/50px-Question_book.svg.png 2x' data-file-
width='252' data-file-height='199' /></a> Artista original: GNOME icon artists, Jorge 2701
• Archivo:Commons-logo.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/4a/Commons-logo.svg Licencia: Public domain
Colaboradores: This version created by Pumbaa, using a proper partial circle and SVG geometry features. (Former versions used to be slightly
warped.) Artista original: SVG version was created by User:Grunt and cleaned up by 3247, based on the earlier PNG version, created by
Reidab.
• Archivo:Computer-aj_aj_ashton_01.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/c/c1/Computer-aj_aj_ashton_01.
svg Licencia: CC0 Colaboradores: ? Artista original: ?
• Archivo:Dg-nova3.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/9/99/Dg-nova3.jpg Licencia: Copyrighted free use Co-
laboradores: Photograph taken by Qu1j0t3. Artista original: User Qu1j0t3 on en.wikipedia
46 CAPÍTULO 11. PROGRAMA INFORMÁTICO
• Archivo:EsquemáticaAlgoritmo1.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/a/a3/Esquem%C3%
A1ticaAlgoritmo1.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Kn
• Archivo:FortranCardPROJ039.agr.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/5/58/FortranCardPROJ039.agr.jpg
Licencia: CC BY-SA 2.5 Colaboradores: I took this picture of an artifact in my possession. The card was created in the late 1960s or
early 1970s and has no copyright notice. Artista original: Arnold Reinhold
• Archivo:Fuente_de_computadora.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/b/be/Fuente_de_computadora.JPG
Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Cesar Eduardo Ballesteros Aguirre
• Archivo:HP_Touchsmart_PC.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/40/HP_Touchsmart_PC.jpg Licencia:
CC BY 2.0 Colaboradores: http://www.flickr.com/photos/36627423@N04/3377516586/ Artista original: Jannet
• Archivo:LampFlowchart-es.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/b/bd/LampFlowchart-es.svg Licencia: CC
BY-SA 3.0 Colaboradores:
• LampFlowchart.svg Artista original: LampFlowchart.svg: svg by Booyabazooka
• Archivo:Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png Fuente: http://upload.wikimedia.org/
wikipedia/commons/3/37/Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png Licencia: CC BY-SA 3.0
Colaboradores: Taking a screenshot, then editing using Paint.NET Artista original: Carrot Lord
• Archivo:PCDESK.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/0/06/PCDESK.JPG Licencia: GFDL Colaboradores:
Trabajo propio Artista original: Almiux2009
• Archivo:PET-basic.png Fuente: http://upload.wikimedia.org/wikipedia/commons/0/0b/PET-basic.png Licencia: Public domain Colabo-
radores: Trabajo propio Artista original: Rafax
• Archivo:Pauscal_lenguaje_de_programación.png Fuente: http://upload.wikimedia.org/wikipedia/commons/3/32/Pauscal_lenguaje_
de_programaci%C3%B3n.png Licencia: CC BY-SA 4.0 Colaboradores: Trabajo propio Artista original: DarkBlueZV
• Archivo:Personal_computer,_exploded_4.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/1/13/Personal_computer%
2C_exploded_4.svg Licencia: CC BY 2.5 Colaboradores: ? Artista original: ?
• Archivo:Pila.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/d/d1/Pila.svg Licencia: CC0 Colaboradores: Image:Data_
stack.svg by User:Boivie. Artista original: User:Boivie, User:Ocaroline
• Archivo:Pilas.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/6/62/Pilas.jpg Licencia: CC BY-SA 4.0 Colaboradores: Tra-
bajo propio Artista original: DarkBlueZV
• Archivo:Programming_language_textbooks.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/a/a0/Programming_
language_textbooks.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: User:K.lee
• Archivo:Python_add5_syntax.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/e/e1/Python_add5_syntax.svg Licencia:
Copyrighted free use Colaboradores: http://en.wikipedia.org/wiki/Image:Python_add5_syntax.png Artista original: Xander89
• Archivo:Rename_icon.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/7/79/Rename_icon.svg Licencia: CC-BY-SA-3.0
Colaboradores: Image:Translation arrow.svg + Image:B with line below.svg, own work Artista original: Angr, Down10, Korrigan, User:
Clarus The Dogcow
• Archivo:Spanish_Wikiquote.SVG Fuente: http://upload.wikimedia.org/wikipedia/commons/1/13/Spanish_Wikiquote.SVG Licencia:
CC BY-SA 3.0 Colaboradores: derived from Wikiquote-logo.svg Artista original: James.mcd.nz
• Archivo:Translation_arrow.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/2/2a/Translation_arrow.svg Licencia: CC-
BY-SA-3.0 Colaboradores: Este gráfico vectorial fue creado con Inkscape. Artista original: Jesse Burgheimer
• Archivo:USB_flash_drive.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/2/2c/USB_flash_drive.JPG Licencia: CC-BY-
SA-3.0 Colaboradores: ? Artista original: ?
• Archivo:Wikibooks-logo-es.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/42/Wikibooks-logo-es.svg Licencia: CC
BY-SA 3.0 Colaboradores: Trabajo propio Artista original: User:Bastique, User:Ramac et al.
• Archivo:Wikibooks-logo.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/f/fa/Wikibooks-logo.svg Licencia: CC BY-SA
3.0 Colaboradores: Trabajo propio Artista original: User:Bastique, User:Ramac et al.
• Archivo:Wikiversity-logo-Snorky.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/1/1b/Wikiversity-logo-en.svg Licen-
cia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Snorky
• Archivo:Wiktionary-logo-es.png Fuente: http://upload.wikimedia.org/wikipedia/commons/0/06/Wiktionary-logo-es.png Licencia: CC
BY-SA 3.0 Colaboradores: originally uploaded there by author, self-made by author Artista original: es:Usuario:Pybalo
11.8.3 Content license
• Creative Commons Attribution-Share Alike 3.0
View publication statsView publication stats

Algoritmosy estructurasdedatos2015 1

  • 1.
  • 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  
  • 3.
    Índice general 1 Computadora1 1.1 Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.1 Unidad central de procesamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.2 Memoria primaria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.3 Periféricos de Entrada, de Salida o de Entrada/Salida . . . . . . . . . . . . . . . . . . . . 3 1.1.4 Buses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Otros conceptos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Etimología de la palabra ordenador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4.2 Tipos de computadoras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4.3 Componentes y periféricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4.4 Otros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.6 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2 Ciencias de la información (tecnología) 7 3 Lenguaje de programación 8 3.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2 Elementos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.2.1 Variables y vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.2.2 Condicionantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2.3 Bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2.4 Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2.5 Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2.6 Semántica estática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.2.7 Sistema de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.3 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.4 Técnica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.4.1 Paradigmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.5 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 i
  • 4.
    ii ÍNDICE GENERAL 3.7Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4 Algoritmo 16 4.1 Definición formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4.2 Medios de expresión de un algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2.1 Diagrama de flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2.2 Pseudocódigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2.3 Sistemas formales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2.4 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2.5 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2.6 Estructuras secuenciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.3 Algoritmos como funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.4 Análisis de algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.5 Ejemplo de algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.5.1 Descripción de alto nivel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.5.2 Descripción formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.5.3 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.6 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.6.1 Tipos de algoritmos según su función . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.6.2 Técnicas de diseño de algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.6.3 Temas relacionados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.6.4 Disciplinas relacionadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.7 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.8 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.9 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5 Algoritmo determinista 22 5.1 Definición formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.2 Cuándo un algoritmo puede volverse no determinista . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.3 Problemas con los algoritmos deterministas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.4 Notas al pie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 5.5 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 6 Estructura de datos 24 6.1 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 6.2 Estructuras de datos en programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 6.3 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 7 Cola (informática) 25 7.1 Usos concretos de la cola . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 7.2 Información adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 7.3 Operaciones Básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 7.4 Implementaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
  • 5.
    ÍNDICE GENERAL iii 7.4.1Colas en Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 7.4.2 Colas en Maude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.4.3 Colas en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.4.4 Colas en JAVA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.4.5 Colas en C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.5 Tipos de colas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 7.6 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 7.7 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 8 Tipo de dato abstracto 28 8.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 8.2 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 8.3 Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 8.4 Separación de la interfaz e implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 8.5 Caracterización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 8.6 La abstracción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 8.7 Ejemplos de uso de TDAs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 8.8 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 9 Vector (informática) 32 9.1 Índices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 9.2 Notación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 9.3 Forma de acceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 9.4 Vectores dinámicos y estáticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 9.4.1 Ejemplos en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 9.5 Vectores multidimensionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 9.6 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 10 Pila (informática) 34 10.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 10.2 Pila como tipo abstracto de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 10.2.1 Operaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 10.2.2 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 10.2.3 Estructuras de datos relacionadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 10.3 Pilas Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 10.4 Arquitectura básica de una pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 10.5 Soporte de Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 10.6 Soporte de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 10.7 Expresión de evaluación y análisis sintáctico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 10.7.1 Tiempo de ejecución de la gestión de memoria . . . . . . . . . . . . . . . . . . . . . . . 37 10.7.2 Solucionar problemas de búsqueda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 10.8 Seguridad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
  • 6.
    iv ÍNDICE GENERAL 10.9Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 10.10Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 11 Programa informático 38 11.1 Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 11.1.1 Paradigmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 11.1.2 Compilado o interpretando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 11.1.3 Programas que se auto-modifican . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 11.2 Ejecución y almacenamiento de los programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 11.2.1 Programas empotrados en hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 11.2.2 Programas cargados manualmente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 11.2.3 Programas generados automáticamente . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 11.2.4 Ejecución simultánea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 11.3 Categorías funcionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 11.4 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 11.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 11.6 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 11.7 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 11.8 Text and image sources, contributors, and licenses . . . . . . . . . . . . . . . . . . . . . . . . . . 43 11.8.1 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 11.8.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 11.8.3 Content license . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
  • 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 CONCEPTOS3 • 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ÉN5 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 dela 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 deprogramació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ódigoFortran 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.3Implementació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 EXTERNOS15 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 nofunciona ¿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 DEEXPRESIÓ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 DEALGORITMO 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 EXTERNOS21 [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 Enciencias 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ÉN23 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 dedatos 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 FinalPrincipio 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
  • 32.
    26 CAPÍTULO 7.COLA (INFORMÁTICA) ColaLongitud:Entero Lec:Longitud FinProp Priva- do: Constructor: Comenzar Destructor: Terminar FinClase 7.4.2 Colas en Maude La ColaNV es la cola no vacía, que diferenciamos de la cola normal a la hora de tomar en cuenta errores. A su vez, el elemento X representa el tipo de valor que puede contener la cola: entero, carácter, registro.... fmod COLA {X :: TRIV} is sorts ColaNV{X} Cola{X} . subsort ColaNV{X} < Cola{X} . *** generadores op crear : -> Cola{X} [ctor] . op encolar : X$Elt Cola{X} -> ColaNV {X} [ctor] . *** constructores op desen- colar : Cola{X} -> Cola{X} . *** selectores op fren- te : ColaNV{X} -> X$Elt . *** variables var C : Co- laNV{X} . vars E E2 : X$Elt . *** ecuaciones eq des- encolar(crear) = crear . eq desencolar(encolar(E, crear)) = crear . eq desencolar(encolar(E, C)) = encolar(E, des- encolar(C)) . eq frente(encolar(E, crear)) = E . eq fren- te(encolar(E, C)) = frente(C) . endfm Especificación de una cola de colas de enteros en Maude: view VInt from TRIV to INT is sort Elt to Int . endv view VColaInt from TRIV to COLA{VInt} is sort Elt to Cola{VInt} . endv fmod COLA-COLAS-INT is protecting INT . protecting COLA{VColaInt} . *** operaciones propias de la cola de colas de enteros op encolarInt : Int Co- laNV{VColaInt} -> ColaNV{VColaInt} . op desenco- larInt : Cola{VColaInt} -> Cola{VColaInt} . op fren- teInt : ColaNV{VColaInt} -> [Int] . *** variables var CCNV : ColaNV{VColaInt} . var CC : Cola{VColaInt} . var CE : Cola{VInt} . var E : Int . *** ecuaciones eq encolarInt(E, encolar(CE, CC)) = encolar(encolar(E, CE), CC) . eq desencolarInt (encolar(CE, crear)) = en- colar(desencolar(CE), crear) . eq desencolarInt (enco- lar(CE, CCNV)) = encolar(CE, desencolarInt(CCNV)) . eq frenteInt(CCNV) = frente(frente(CCNV)) . endfm 7.4.3 Colas en C++ #ifndef COLA #define COLA // Define la cola using namespace std; template <class T> class Cola{ private: struct Nodo{ T elemento; struct Nodo* siguiente; // coloca el nodo en la segunda posición }* primero; struct Nodo* ultimo; unsigned int elementos; public: Cola(){ elementos = 0; } cout<<" Hola Mundo! " <<endl; cout<<" Hello, World! " <<endl; ~Cola(){ while (elementos != 0) pop(); } void push(const T& elem){ Nodo* aux = new Nodo; aux->elemento = elem; if (elementos == 0) primero = aux; else ultimo->siguiente = aux; ultimo = aux; ++elementos; } void pop(){ Nodo* aux = primero; primero = primero->siguiente; delete aux; --elementos; } T consultar() const{ return primero- >elemento; } bool vacia() const{ return elementos == 0; } unsigned int size() const{ return elementos; } }; #endif 7.4.4 Colas en JAVA public void inserta(Elemento x) { Nodo Nuevo; Nuevo = new Nodo(x, null); if (NodoCabeza == null) { NodoCa- beza = Nuevo; } else { NodoFinal.Siguiente = Nuevo; } NodoFinal = Nuevo; } public Elemento cabeza() throws IllegalArgumentException { if (NodoCabeza == null) { throw new IllegalArgumentException(); } else { return NodoCabeza.Info; } } public Cola() { // Devuelve una Cola vacía NodoCabeza = null; NodoFinal = null; } 7.4.5 Colas en C# public partial class frmPrincipal { // Variables glo- bales public static string[] Cola; public static int Frente; public static int Final; public static int N; [STAThread] public static void Main(string[] args) { Application.EnableVisualStyles(); Appli- cation.SetCompatibleTextRenderingDefault(false); Application.Run(new frmPrincipal()); } public frmPrin- cipal() // Constructor { InitializeComponent(); Cola = new string[5]; // Arreglo lineal de 5 N = 4; Frente = −1; Final = −1; } void CmdInsercionClick(object sender, System.EventArgs e) { frmInsercion Inser- cion = new frmInsercion(); Insercion.Show(); } void CmdRecorridoClick(object sender, System.EventArgs e) { frmRecorrido Recorrido = new frmRecorrido(); Recorrido.Show(); } void CmdBusquedaClick(object sender, EventArgs e) { frmBusqueda Busqueda = new frmBusqueda(); Busqueda.Show(); } void CmdElimina- cionClick(object sender, EventArgs e) { frmEliminacion Eliminar = new frmEliminacion(); Eliminar.Show(); } } Algoritmo Insertar(Cola, N, Frente, Final, Elemento) void CmdInsertarClick(object sender, System.EventArgs e) { elemento = txtInsercion.Text; // Se verifica que haya espacio en la Cola if (frmPrincipal.Frente == 0 && frmPrincipal.Final == frmPrincipal.N) { Mes- sageBox.Show(“La Cola esta llena”); return; } if (frmPrincipal.Frente == frmPrincipal.Final + 1) { Mes- sageBox.Show(“La Cola esta llena”); return; } // Si la cola esta vacia se inicializan punteros if (frmPrincipal.Frente == −1) { frmPrincipal.Frente = 0; frmPrincipal.Final = 0; } else if (frmPrincipal.Final == frmPrincipal.N) { frmPrincipal.Final = 0; } else { frmPrincipal.Final = frmPrincipal.Final + 1; } // Se agrega elemento a la Cola frmPrincipal.Cola[frmPrincipal.Final] = elemento; txtInsercion.Text = ""; } Algoritmo Eliminación (Cola, Frente, Final, N) void CmdEliminarClick(object sender, EventArgs e) { if (frmPrincipal.Frente == −1) { Message- Box.Show(“Cola Vacia”); return; } string elemento = frmPrincipal.Cola[frmPrincipal.Frente]; // si la cola tiene un solo elemento if (frmPrincipal.Frente ==
  • 33.
    7.6. VÉASE TAMBIÉN27 frmPrincipal.Final) { frmPrincipal.Frente = −1; frm- Principal.Final = −1; } else if (frmPrincipal.Frente == frmPrincipal.N) { frmPrincipal.Frente = 0; } else { frmPrincipal.Frente = frmPrincipal.Frente + 1; } lsEliminado.Items.Add(elemento); } Otra forma de programar una cola en Java Por Jorge He- rrera C import java.util.*; public class Cola <Tipo>{ private List<Tipo> cola; public Cola(){ cola=new Array- List<Tipo>(); } public boolean colaVacia(){ return cola.isEmpty(); } public void agregar(Tipo elemen- to){ cola.add(elemento); } public Tipo sacar(){ if(colaVacia())return null; Tipo elemento=cola.get(0); cola.remove(0); return elemento; } }// Fin de la clase Cola A continuación un ejemplo de una clase manejadora de la clase Cola public class Manejador { public static void main(String[] args) { Cola cola=new <Inte- ger>Cola(); System.out.println(cola.sacar()); cola.agregar(23); cola.agregar(24); co- la.agregar(25); while(!cola.colaVacia()){ Sys- tem.out.println(cola.sacar()); } Cola nombres=new <String>Cola(); nombres.agregar(“Jorge”); nom- bres.agregar(“Raquel”); nombres.agregar(“Mayra Alejandra”); while(!nombres.colaVacia()){ Sys- tem.out.println(nombres.sacar()); } } }// Fin de la clase Manejadora 7.5 Tipos de colas • Colas circulares (anillos): en las que el último ele- mento y el primero están unidos. • Colas de prioridad: En ellas, los elementos se atien- den en el orden indicado por una prioridad asocia- da a cada uno. Si varios elementos tienen la misma prioridad, se atenderán de modo convencional según la posición que ocupen. Hay 2 formas de implemen- tación: 1. Añadir un campo a cada nodo con su prioridad. Re- sulta conveniente mantener la cola ordenada por or- den de prioridad. 2. Crear tantas colas como prioridades haya, y alma- cenar cada elemento en su cola. • Bicolas: son colas en donde los nodos se pueden aña- dir y quitar por ambos extremos; se les llama DE- QUE (Double Ended QUEue). Para representar las bicolas lo podemos hacer con un array circular con Inicio y Fin que apunten a cada uno de los extremos. Hay variantes: • Bicolas de entrada restringida: Son aquellas donde la inserción sólo se hace por el final, aunque podemos eliminar al inicio ó al final. • Bicolas de salida restringida: Son aquellas donde só- lo se elimina por el final, aunque se puede insertar al inicio y al final. 7.6 Véase también • Pila (estructura de datos) • Lista (estructura de datos) • Cola de prioridad (estructura de datos) • Cola circular • Bicola 7.7 Enlaces externos
  • 34.
    Capítulo 8 Tipo dedato abstracto Un tipo de dato abstracto (TDA) o tipo abstracto de datos (TAD) es un modelo matemático compuesto por una colección de operaciones definidas sobre un conjunto de datos para el modelo. 8.1 Introducción En el mundo de la programación existen diversos lenguajes que se han ido creando con el paso del tiempo y que se han perfeccionado debido a las necesidades de los programadores de la época a la que pertenecen. Los primeros lenguajes de programación eran de tipo lineal, ya que un programa se recorría desde un punto marcado como Inicio hasta llegar a un punto Fin. Con el tiempo se fueron creando nuevos lenguajes y en nuestros días los más utilizados son los llamados “orientados a objetos”. Los lenguajes orientados a objetos (LOO) tienen la ca- racterística de que no son lenguajes lineales, sino que se forman de diversas funciones, las cuales son llamadas en el orden en que el programa mismo las pide o el usuario determina. Para entender mejor cómo funcionan los len- guajes orientados a objetos, vamos a introducir un con- cepto fundamental en las Estructuras de Datos denomi- nado Abstracción de Datos y que es parte importante de estos Lenguajes y de la manera en que funciona la mayo- ría del software comercial de nuestros días. 8.2 Historia El concepto de tipo de dato abstracto (TDA, Abstract Da- ta Type), fue propuesto por primera vez hacia 1974 por John Guttag y otros, pero no fue hasta 1975 que por pri- mera vez Liskov lo propuso para el lenguaje CLU. El lenguaje Turbo Pascal fue determinante para la común aceptación de los TDA con la introducción de las Units, si bien estas no cumplen con las características básicas de un tipo de dato abstracto como por ejemplo la encapsu- lación de los datos. El lenguaje Ada pudo implementar exitosamente los TDAs con sus Packages. Vale recordar que estos dos últimos lenguajes soportan formalmente la Programación modular. 8.3 Definición Con mucha frecuencia se utilizan los términos TDA y Abstracción de Datos de manera equivalente, y esto es debido a la similitud e interdependencia de ambos. Sin embargo, es importante definir por separado los dos con- ceptos. Como ya se mencionó, los Lenguajes de Programación Orientados a Objetos son lenguajes formados por dife- rentes métodos o funciones y que son llamados en el or- den en que el programa lo requiere, o el usuario lo desea. La abstracción de datos consiste en ocultar las caracterís- ticas de un objeto y obviarlas, de manera que solamente utilizamos el nombre del objeto en nuestro programa. Es- to es similar a una situación de la vida cotidiana. Cuando yo digo la palabra “perro”, usted no necesita que yo le di- ga lo que hace el perro. Usted ya sabe la forma que tiene un perro y también sabe que los perros ladran. De mane- ra que yo abstraigo todas las características de todos los perros en un solo término, al cual llamo “perro”. A esto se le llama ‘Abstracción’ y es un concepto muy útil en la programación, ya que un usuario no necesita mencionar todas las características y funciones de un objeto cada vez que éste se utiliza, sino que son declaradas por sepa- rado en el programa y simplemente se utiliza el término abstracto (“perro”) para mencionarlo. En el ejemplo anterior, “perro” es un Tipo de Dato Abs- tracto y todo el proceso de definirlo, implementarlo y mencionarlo es a lo que llamamos Abstracción de Datos. Vamos a poner un ejemplo real de la programación. Supongamos que en algún Lenguaje de Programación Orientado a Objetos un pequeño programa saca el área de un rectángulo de las dimensiones que un usuario decida. Pensemos también que el usuario probablemente quiera saber el área de varios rectángulos. Sería muy tedioso pa- ra el programador definir la multiplicación de ‘base’ por ‘altura’ varias veces en el programa, además que limitaría al usuario a sacar un número determinado de áreas. Por ello, el programador puede crear una función denomina- da ‘Área’, la cual va a ser llamada el número de veces que sean necesitadas por el usuario y así el programador se evita mucho trabajo, el programa resulta más rápido, más eficiente y de menor longitud. Para lograr esto, se crea el 28
  • 35.
    8.5. CARACTERIZACIÓN 29 métodoÁrea de una manera separada de la interfaz grá- fica presentada al usuario y se estipula ahí la operación a realizar, devolviendo el valor de la multiplicación. En el método principal solamente se llama a la función Área y el programa hace el resto. Al hecho de guardar todas las características y habilida- des de un objeto por separado se le llama Encapsulamien- to y es también un concepto importante para entender la estructuración de datos. Es frecuente que el Encapsula- miento sea usado como un sinónimo del Ocultación de información, aunque algunos creen que no es así . 8.4 Separación de la interfaz e im- plementación Cuando se usa en un programa de computación, un TDA es representado por su interfaz, la cual sirve como cu- bierta a la correspondiente implementación. La idea es que los usuarios de un TDA tengan que preocuparse só- lo por la interfaz, pero no por la implementación, ya que esta puede ir cambiando con el tiempo y, si no existiera encapsulación, afectar a los programas que usan el dato. Esto se basa en el concepto de Ocultación de informa- ción, una protección para el programa de decisiones de diseño que son objeto de cambio. La solidez de un TDA reposa en la idea de que la im- plementación está escondida al usuario. Solo la interfaz es pública. Esto significa que el TDA puede ser imple- mentado de diferentes formas, pero mientras se manten- ga consistente con la interfaz, los programas que lo usan no se ven afectados. Hay una diferencia, aunque a veces sutil, entre el Tipo de Dato Abstracto y la Estructura de Dato usada en su im- plementación. Por ejemplo, un TDA de una lista puede ser implementado mediante un Arreglo o una Lista Enla- zada o hasta un Árbol binario de búsqueda. Una lista es un Tipo de Dato Abstracto con operaciones bien defini- das (agregar elemento, agregar al final, agregar al princi- pio, recuperar, eliminar, etc) mientras una lista enlazada es una estructura de datos basada en punteros o referen- cias (dependiendo del lenguaje) que puede ser usada para crear una representación de una Lista. La Lista Enlazada es comúnmente usada para representar una TDA Lista, y a veces, hasta confundida. Un ejemplo es la clase Linked List de Java, la cual ofrece una gran cantidad de métodos que no corresponden a una Lista Enlazada “pura”, sino a un fuerte TDA. De forma similar, un TDA Árbol binario de búsqueda puede ser representado de muchas maneras: Árbol bina- rio, Árbol AVL, Árbol rojo-negro, Arreglo, etc. A pesar de la implementación un Árbol binario siempre tiene las mismas operaciones (insertar, eliminar, encontrar, etc.) Separar la interfaz de la implementación no siempre sig- nifica que el usuario ignora totalmente la implementación de la rutina, pero lo suficiente para no depender de nin- gún aspecto de la implementación. Por ejemplo, un TDA puede ser creado usando un script o cualquiera que pueda ser decompilado (como C). En la terminología de Lenguaje Orientado a Objeto, un TDA es una clase; una instancia de un TDA o clase, es un objeto. Además es utilizado constantemente por pro- gramadores de computadoras. 8.5 Caracterización Un TDA está caracterizado por un conjunto de operacio- nes (funciones) al cual se denomina usualmente como in- terfaz pública y representa el comportamiento del TDA; mientras que la implementación como la parte privada del TDA está oculta al programa cliente que lo usa. Todos los lenguajes de alto nivel tienen predefinidos TDA; que son los tipos denominados simples y las estructuras predefi- nidas, y estos tienen sus interfaces públicas que incluyen las operaciones como la +, -, *, etc. no se necesita co- nocer como actúan tales operadores sobre la representa- ción interna de los tipos definidos, que además, suele ser una implementación bastante dependiente de la máqui- na sobre la que trabaje el compilador. Lo interesante es que los lenguajes actuales nos van a permitir ampliar los TDA predefinidos con otros que serán definidos por el propio programador para adecuar así los tipos de datos a las necesidades de los programas. Los TDA que nos van a interesar de ahora en adelante son aquellos que reflejen cierto comportamiento organi- zando cierta variedad de datos estructuradamente. A esta forma estructurada de almacenar los datos será a la que nos refiramos para caracterizar cada TDA. Los TDA que tienen informaciones simples pero depen- dientes de un comportamiento estructural serán llamados polilíticos y aquellos TDA simples, como son los tipos predefinidos donde la información no es relacionada me- diante ninguna estructura y no admiten más que un valor en cada momento serán denominados TDA monolíticos. Nótese que cuando hablemos de un TDA no haremos nin- guna alusión al tipo de los elementos sino tan sólo a la for- ma en que están dispuestos estos elementos. Sólo nos in- teresa la estructura que soporta la información y sus ope- raciones. Para determinar el comportamiento estructural basta con observar la conducta que seguirán los datos. Caractericemos entonces los TDA. Un TDA tendrá una parte que será invisible al usuario la cual hay que prote- ger y que se puede decir que es irrelevante para el uso del usuario y está constituida tanto por la maquinaria algorít- mica que implemente la semántica de las operaciones co- mo por los datos que sirvan de enlace entre los elementos del TDA, es decir, información interna necesaria para la implementación que se esté haciendo para ese comporta- miento del TDA. Resumiendo podemos decir, que tanto la implementación de las operaciones como los elemen-
  • 36.
    30 CAPÍTULO 8.TIPO DE DATO ABSTRACTO tos internos del TDA serán privados al acceso externo y ocultos a cualquier otro nivel. Un TDA representa una abstracción: • Se destacan los detalles (normalmente pocos) de la especificación (el qué). • Se ocultan los detalles (casi siempre numerosos) de la implementación (el cómo). 8.6 La abstracción La abstracción, una de las herramientas que más nos ayu- da a la hora de solucionar un problema, es un mecanismo fundamental para la comprensión de problemas y fenó- menos que poseen una gran cantidad de detalles, su idea principal consiste en manejar un problema, fenómeno, objeto, tema o idea como un concepto general, sin consi- derar la gran cantidad de detalles que estos puedan tener. El proceso de abstracción presenta dos aspectos comple- mentarios. 1. Destacar los aspectos relevantes del objeto. 2. Ignorar los aspectos irrelevantes del mismo (la irre- levancia depende del nivel de abstracción, ya que si se pasa a niveles más concretos, es posible que cier- tos aspectos pasen a ser relevantes). De modo general podemos decir que la abstracción per- mite establecer un nivel jerárquico en el estudio de los fenómenos, el cual se establece por niveles sucesivos de detalles. Generalmente, se sigue un sentido descendente de detalles, desde los niveles más generales a los niveles más concretos. Por ejemplo: los lenguajes de programación de alto nivel permiten al programador abstraerse del sin fin de detalles de los lenguajes ensambladores. Otro ejemplo, la memo- ria de la computadora es una estructura unidimensional formada por celdas y sin embargo trabajamos como si fuera única. La abstracción nos brinda la posibilidad de ir definiendo una serie de refinamientos sucesivos a nuestro TDA y entiéndase bien que cuando decimos refinamien- tos sucesivos nos estamos refiriendo a la estrategia que se utiliza para descomponer un problema en subproblemas. Conforme evoluciona el diseño de software a cada nivel de módulos se representa un refinamiento en el nivel de abstracción. Esto es, incluir detalles que fueron obviados en un nivel superior, en un nivel más bajo de la jerarquía. Veamos los diferentes tipos de abstracción que podemos encontrar en un programa: 1. Abstracción funcional: crear procedimientos y fun- ciones e invocarlos mediante un nombre donde se destaca qué hace la función y se ignora cómo lo hace. El usuario sólo necesita conocer la especificación de la abstracción (el qué) y puede ignorar el resto de los detalles (el cómo). 2. Abstracción de datos: • Tipo de datos: proporcionado por los leguajes de alto nivel. La representación usada es invisible al programador, al cual solo se le permite ver las ope- raciones predefinidas para cada tipo. • Tipos definidos: por el programador que posibili- tan la definición de valores de datos más cercanos al problema que se pretende resolver. • TDA: para la definición y representación de tipos de datos (valores + operaciones), junto con sus propie- dades. • Objetos: Son TDA a los que se añade propiedades de reutilización y de compartición de código. Si profundizamos más al mundo de la programación y sus conceptos, existen dos de estos conceptos que no se deben confundir, ellos son: tipo de datos y estructura de datos. Un tipo de dato, en un lenguaje de programación, defi- ne un conjunto de valores que una determinada variable puede tomar, así como las operaciones básicas sobre di- cho conjunto. Ahora veamos como se van relacionando estos conceptos. Los tipos de datos constituyen un primer nivel de abstracción, ya que no se tiene en cuenta cómo se implementan o se representan realmente la informa- ción sobre la memoria de la máquina. Para el usuario, el proceso de implementación o representación es invisible. Veamos entonces que son las estructuras de datos. Las estructuras de datos son colecciones de variables, no ne- cesariamente del mismo tipo, relacionadas entre sí de al- guna forma. Las estructuras de datos están caracterizadas por el tipo de dato de los elementos guardados en la es- tructura y por la relación definida sobre estos elementos. Al nivel de las estructuras de datos son totalmente irre- levantes las operaciones sobre un elemento en particular, solamente tienen carácter relevante las operaciones que envuelvan la estructura de forma global. La abstracción de datos es la característica de un sistema de bases de datos, que permite al usuario o programador operar con los datos sin necesidad de conocer detalles que para él no son de “importancia”, ofreciendo así una visión abstracta de estos. Para cumplir con tal fin se han definido diferentes niveles de abstracción: [1] • Nivel Físico. Determina como están almacenados fí- sicamente los datos (pistas, sectores, cilindros), re- presenta el nivel más bajo. • Nivel Lógico o Conceptual. Determina la organiza- ción de los archivos. Índices, llaves, orden de cam- pos, relaciones, tipos de datos. • Nivel de Vistas. Oculta parte de la información a los usuarios, es decir hace visible solo una parte de la base de datos.
  • 37.
    8.8. REFERENCIAS 31 8.7Ejemplos de uso de TDAs Algunos ejemplos del uso de TDAs en programación son: • Conjuntos: Implementación de conjuntos con sus operaciones básicas (unión, intersección y diferen- cia), operaciones de inserción, borrado, búsqueda... • Árboles Binarios de Búsqueda: Implementación de árboles de elementos, utilizados para la represen- tación interna de datos complejos. Aunque siempre se los toma como un TDA separado son parte de la familia de los grafos. • Pilas y Colas: Implementación de los algoritmos FIFO y LIFO. • Grafos: Implementación de grafos; una serie de vér- tices unidos mediante una serie de arcos o aristas. 8.8 Referencias [1] http://blogdecomputacion.com/blog/2010/08/21/ que-es-la-abstraccion-de-datos-y-modelos-de-datos/
  • 38.
    Capítulo 9 Vector (informática) 01 2 3 4 5 6 7 8 9 Matriz unidimensional con 10 elementos. En programación, una matriz o vector (llamado en inglés array) es una zona de almacenamiento continuo, que con- tiene una serie de elementos del mismo tipo, los elemen- tos de la matriz. Desde el punto de vista lógico una matriz se puede ver como un conjunto de elementos ordenados en fila (o filas y columnas si tuviera dos dimensiones). En principio, se puede considerar que todas las matrices son de una dimensión, la dimensión principal, pero los elementos de dicha fila pueden ser a su vez matrices (un proceso que puede ser recursivo), lo que nos permite ha- blar de la existencia de matrices multidimensionales, aun- que las más fáciles de imaginar son los de una, dos y tres dimensiones. Estas estructuras de datos son adecuadas para situacio- nes en las que el acceso a los datos se realice de forma aleatoria e impredecible. Por el contrario, si los elemen- tos pueden estar ordenados y se va a utilizar acceso se- cuencial sería más adecuado utilizar una lista, ya que esta estructura puede cambiar de tamaño fácilmente durante la ejecución de un programa. 9.1 Índices Todo vector se compone de un determinado número de elementos. Cada elemento es referenciado por la posición que ocupa dentro del vector. Dichas posiciones son llama- das índice y siempre son correlativos. Existen tres formas de indexar los elementos de una matriz: • Indexación base-cero (0): en este modo el primer elemento del vector será la componente cero ('0') del mismo, es decir, tendrá el índice '0'. En conse- cuencia, si el vector tiene 'n' componentes la última tendrá como índice el valor 'n-1'. El lenguaje C es un ejemplo típico que utiliza este modo de indexación. • Indexación base-uno (1): en esta forma de indexa- ción, el primer elemento de la matriz tiene el índice '1' y el último tiene el índice 'n' (para una matriz de 'n' componentes). • Indexación base-n (n): este es un modo versátil de indexación en la que el índice del primer elemen- to puede ser elegido libremente, en algunos lengua- jes de programación se permite que los índices pue- dan ser negativos e incluso de cualquier tipo escalar (también cadenas de caracteres). 9.2 Notación La representación de un elemento en un vector se sue- le hacer mediante el identificador del vector seguido del índice entre corchetes, paréntesis o llaves: Aunque muchas veces en pseudocódigo y en libros de matemática se representan como letras acompañadas de un subíndice numérico que indica la posición a la que se quiere acceder. Por ejemplo, para un vector "A": A0, A1, A2, ... (vector unidimensional) 9.3 Forma de acceso La forma de acceder a los elementos de la matriz es di- recta; esto significa que el elemento deseado es obtenido a partir de su índice y no hay que ir buscándolo elemento por elemento (en contraposición, en el caso de una lis- ta, para llegar, por ejemplo, al tercer elemento hay que acceder a los dos anteriores o almacenar un apuntador o puntero que permita acceder de manera rápida a ese ele- mento). Para trabajar con vectores muchas veces es preciso reco- rrerlos. Esto se realiza por medio de bucles. El siguiente pseudocódigo muestra un algoritmo típico para recorrer un vector y aplicar una función ' f(...) ' a cada una de las componentes del vector: i = 0 mientras (i < longitud) //Se realiza alguna opera- ción con el vector en la i-ésima posición f(v[i]) i=i+1 fin_mientras 32
  • 39.
    9.5. VECTORES MULTIDIMENSIONALES33 9.4 Vectores dinámicos y estáticos Lo habitual es que un vector tenga una cantidad fija de memoria asignada, aunque dependiendo del tipo de vec- tor y del lenguaje de programación un vector podría tener una cantidad variable de datos. En este caso, se les deno- mina vectores dinámicos, en oposición, a los vectores con una cantidad fija de memoria asignada se los deno- mina vectores estáticos. El uso de vectores dinámicos requiere realizar una apro- piada gestión de memoria dinámica. Un uso incorrecto de los vectores dinámicos, o mejor dicho, una mala ges- tión de la memoria dinámica, puede conducir a una fuga de memoria. Al utilizar vectores dinámicos siempre ha- brá que liberar la memoria utilizada cuando ésta ya no se vaya a seguir utilizando. Lenguajes más modernos y de más alto nivel, cuentan con un mecanismo denominado recolector de basura (como es el caso de Java) que permiten que el programa decida si debe liberar el espacio basándose en si se va a utilizar en el futuro o no un determinado objeto. 9.4.1 Ejemplos en C • Declaración en C/C++ de un vector estático. int main(void) { int i, v[5]; // v[5] es un vector de 5 componentes for(i=0; i<5; i++) { v[i] = 0; // Asignamos un valor printf("%dn”, v[i]); printf("n”); // Crea una nueva línea } return 0 } • Declaración en C/C++ de un vector estático utili- zando aritmética de punteros. Siendo el identificador del vector, un puntero constante que contiene la dirección del comienzo del vector (vec- tor[0], primer elemento) int main(void) { int i, v[5]; // v[5] es un vector de 5 componentes for(i=0; i<5; i++) { *(v + i) = 0; // Asignamos un valor en la dirección (vector + ((índice * sizeof (int) cantidad de bytes de desplazamiento desde la base.) printf("%dn”, *(vector + i)); printf("n”); // Crea una nueva línea } return 0 } • Declaración en C++ de un vector de STL: #include <vector> vector<int> v; // Si no se espe- cifica el tamaño inicial es 0 for(int i=0 ;i<5 ;i++) { v.push_back(2*i); // inserta un elemento al final del vector } El ejemplo anterior está hecho para el lenguaje C++. En C, para crear vectores dinámicos se tendrían que utilizar las instrucciones malloc y realloc para reservar memoria de forma dinámica (ver biblioteca stdlib.h), y la función free para liberar la memoria utilizada. Resultado: El resultado de los dos ejemplos es el mismo vector. 9.5 Vectores multidimensionales En Basic, Java y otros lenguajes es posible declarar matri- ces multidimensionales, entendiéndolas como un vector de x dimensión. En dichos casos en número de elementos del vector es el producto resultante de cada dimensión. Por ejemplo el vector v(4,1) tiene 10 elementos se calcula del siguiente modo: (0-4) * (0-1). Los elementos de la primera dimensión del vector contiene 5 elementos que van del '0' al '4' y la 2º dimensión tiene 2 elementos que van desde '0' a '1'. Los elementos serían accedidos del siguiente modo: elemento 1: (0,0) elemento 2: (0,1) elemento 3: (1,0) ... elemento 8: (3,1) elemento 9: (4,0) elemento 10: (4,1) 9.6 Véase también • Estructura de datos • Registro (estructura de datos) • Programación orientada a objetos • Gráfico vectorial • Tupla
  • 40.
    Capítulo 10 Pila (informática) DesapilarApilar Representaciónsimplificada de una pila Pilas para niños Una pila (stack en inglés) es una lista ordenada o estructura de datos en la que el modo de acceso a sus ele- mentos es de tipo LIFO (del inglés Last In First Out, últi- mo en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el área de informática debido a su sim- plicidad y ordenación implícita de la propia estructura. Para el manejo de los datos se cuenta con dos operaciones básicas: apilar (push), que coloca un objeto en la pila, y su operación inversa, retirar (o desapilar, pop), que retira el último elemento apilado. En cada momento sólo se tiene acceso a la parte superior de la pila, es decir, al último objeto apilado (denominado TOS, Top of Stack en inglés). La operación retirar per- mite la obtención de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con ante- rioridad), que pasa a ser el nuevo TOS. Por analogía con objetos cotidianos, una operación apilar equivaldría a colocar un plato sobre una pila de platos, y una operación retirar a retirarlo. Las pilas suelen emplearse en los siguientes contextos: • Evaluación de expresiones en notación postfija (notación polaca inversa). • Reconocedores sintácticos de lenguajes indepen- dientes del contexto • Implementación de recursividad. 10.1 Historia El método de pila para la evaluación de expresiones fue propuesto en 1955 y dos años después patentado por Frie- drich L. Bauer, quién recibió en 1988 el premio “IEEE Computer Society Pioneer Award” por su trabajo en el desarrollo de dicha estructura de datos. 10.2 Pila como tipo abstracto de datos A modo de resumen tipo de datos, la pila es un conte- nedor de nodos y tiene dos operaciones básicas: push (o apilar) y pop (o desapilar). 'Push' añade un nodo a la par- te superior de la pila, dejando por debajo el resto de los nodos. 'Pop' elimina y devuelve el actual nodo superior de la pila. Una metáfora que se utiliza con frecuencia es la idea de una pila de platos en una cafetería con muelle de pila. En esa serie, sólo la primera placa es visible y acce- sible para el usuario, todas las demás placas permanecen ocultas. Como se añaden las nuevas placas, cada nueva placa se convierte en la parte superior de la pila, escondi- dos debajo de cada plato, empujando a la pila de placas. 34
  • 41.
    10.4. ARQUITECTURA BÁSICADE UNA PILA 35 A medida que la placa superior se elimina de la pila, la segunda placa se convierte en la parte superior de la pila. Dos principios importantes son ilustrados por esta metá- fora: En primer lugar la última salida es un principio, la segunda es que el contenido de la pila está oculto. Sólo la placa de la parte superior es visible, por lo que para ver lo que hay en la tercera placa, el primer y segundo platos tendrán que ser retirados. 10.2.1 Operaciones Una pila cuenta con 2 operaciones imprescindibles: apilar y desapilar, a las que en las implementaciones modernas de las pilas se suelen añadir más de uso habitual. • Crear: se crea la pila vacía. (constructor) • Tamaño: regresa el número de elementos de la pila. (size) • Apilar: se añade un elemento a la pila.(push) • Desapilar: se elimina el elemento frontal de la pi- la.(pop) • Cima: devuelve el elemento que esta en la cima de la pila. (top o peek) • Vacía: devuelve cierto si la pila está sin elementos o falso en caso de que contenga uno. (empty). 10.2.2 Implementación Un requisito típico de almacenamiento de una pila de n elementos es O(n). El requisito típico de tiempo de O(1) las operaciones también son fáciles de satisfacer con un array o con listas enlazadas simples. 10.2.3 Estructuras de datos relacionadas El tipo base de la estructura FIFO (el primero en entrar es el primero en salir)es la cola, y la combinación de las operaciones de la pila y la cola es proporcionado por el deque. Por ejemplo, el cambio de una pila en una cola en un algoritmo de búsqueda puede cambiar el algoritmo de búsqueda en primera profundidad (en inglés, DFS) por una búsqueda en amplitud (en inglés, BFS). Una pila aco- tada es una pila limitada a un tamaño máximo impuesto en su especificación. 10.3 Pilas Hardware Un uso muy común de las pilas a nivel de arquitectura hardware es la asignación de memoria. 10.4 Arquitectura básica de una pi- la Una pila típica es un área de la memoria de los compu- tadores con un origen fijo y un tamaño variable. Al prin- cipio, el tamaño de la pila es cero. Un puntero de pila, por lo general en forma de un registro de hardware, apunta a la más reciente localización en la pila; cuando la pila tie- ne un tamaño de cero, el puntero de pila de puntos en el origen de la pila. Las dos operaciones aplicables a todas las pilas son: • Una operación apilar, en el que un elemento de datos se coloca en el lugar apuntado por el puntero de pila, y la dirección en el puntero de pila se ajusta por el tamaño de los datos de partida. • Una operación desapilar: un elemento de datos en la ubicación actual apuntado por el puntero de pila es eliminado, y el puntero de pila se ajusta por el tamaño de los datos de partida. Hay muchas variaciones en el principio básico de las ope- raciones de pila. Cada pila tiene un lugar fijo en la me- moria en la que comienza. Como los datos se añadirán a la pila, el puntero de pila es desplazado para indicar el es- tado actual de la pila, que se expande lejos del origen (ya sea hacia arriba o hacia abajo, dependiendo de la aplica- ción concreta). Por ejemplo, una pila puede comenzar en una posición de la memoria de mil, y ampliar por debajo de las direc- ciones, en cuyo caso, los nuevos datos se almacenan en lugares que van por debajo de 1000, y el puntero de pila se decrementa cada vez que un nuevo elemento se agre- ga. Cuando un tema es eliminado de la pila, el puntero de pila se incrementa. Los punteros de pila pueden apuntar al origen de una pila o de un número limitado de direcciones, ya sea por enci- ma o por debajo del origen (dependiendo de la dirección en que crece la pila), sin embargo el puntero de pila no puede cruzar el origen de la pila. En otras palabras, si el origen de la pila está en la dirección 1000 y la pila crece hacia abajo (hacia las direcciones 999, 998, y así sucesi- vamente), el puntero de pila nunca debe ser incrementado más allá de 1000 (para 1001, 1002, etc.) Si un desapilar operación en la pila hace que el puntero de pila se deje atrás el origen de la pila, una pila se produce desborda- miento. Si una operación de apilar hace que el puntero de pila incremente o decremente más allá del máximo de la pila, en una pila se produce desbordamiento. La pila es visualizada ya sea creciente de abajo hacia arri- ba (como pilas del mundo real), o, con el máximo elemen- to de la pila en una posición fija, o creciente, de izquierda a derecha, por lo que el máximo elemento se convierte en el máximo a “la derecha”. Esta visualización puede ser in- dependiente de la estructura real de la pila en la memoria.
  • 42.
    36 CAPÍTULO 10.PILA (INFORMÁTICA) Esto significa que rotar a la derecha es mover el primer elemento a la tercera posición, la segunda a la primera y la tercera a la segunda. Aquí hay dos equivalentes visua- lizaciones de este proceso: Manzana Plátano Plátano ==rotar a la derecha==> Fresa Fresa Manzana Fresa Manzana Plátano ==rotar a la izquierda==> Fresa Manzana Plátano Una pila es normalmente representada en los ordenadores por un bloque de celdas de memoria, con los “de abajo” en una ubicación fija, y el puntero de pila de la dirección actual de la “cima” de células de la pila. En la parte supe- rior e inferior se utiliza la terminología con independen- cia de que la pila crece realmente a la baja de direcciones de memoria o direcciones de memoria hacia mayores. Apilando un elemento en la pila,se ajusta el puntero de pila por el tamaño de elementos (ya sea decrementar o incrementar, en función de la dirección en que crece la pila en la memoria), que apunta a la próxima celda, y copia el nuevo elemento de la cima en área de la pila. Dependiendo de nuevo sobre la aplicación exacta, al fi- nal de una operación de apilar, el puntero de pila puede señalar a la siguiente ubicación no utilizado en la pila, o tal vez apunte al máximo elemento de la pila. Si la pila apunta al máximo elemento de la pila, el puntero de pila se actualizará antes de que un nuevo elemento se apile, si el puntero que apunta a la próxima ubicación disponible en la pila, que se actualizará después de que el máximo elemento se apile en la pila. Desapilando es simplemente la inversa de apilar. El pri- mer elemento de la pila es eliminado y el puntero de pila se actualiza, en el orden opuesto de la utilizada en la ope- ración de apilar. 10.5 Soporte de Hardware Muchas CPUs tienen registros que se pueden utilizar co- mo punteros de pila. Algunos, como el Intel x86, tienen instrucciones especiales que implícitamente el uso de un registro dedicado a la tarea de ser un puntero de pila. Otros, como el DEC PDP-11 y de la familia 68000 de Motorola tienen que hacer frente a los modos de hacer posible la utilización de toda una serie de registros como un puntero de pila. La serie Intel 80x87 numérico de co- processors tiene un conjunto de registros que se puede ac- ceder ya sea como una pila o como una serie de registros numerados. Algunos microcontroladores, por ejemplo al- gunos PICs, tienen un fondo fijo de pila que no es direc- tamente accesible. También hay una serie de microproce- sadores que aplicar una pila directamente en el hardware: • Computer vaqueros MuP21 • Harris RTX línea • Novix NC4016 Muchas pilas basadas en los microprocesadores se uti- lizan para aplicar el lenguaje de programación Forth en el nivel de microcódigo. Pila también se utilizaron co- mo base de una serie de mainframes y miniordenadores. Esas máquinas fueron llamados pila de máquinas, el más famoso es el Burroughs B5000 10.6 Soporte de Software En programas de aplicación escrito en un lenguaje de al- to nivel, una pila puede ser implementada de manera efi- ciente, ya sea usando vectores o listas enlazadas. En LISP no hay necesidad de aplicar la pila, puesto que las funcio- nes apilar y desapilar están disponibles para cualquier lis- ta. Adobe PostScript también está diseñada en torno a una pila que se encuentra directamente visible y manipuladas por el programador. El uso de las pilas está muy presente en el desarrollo de software por ello la importancia de las pilas como tipo abstracto de datos. 10.7 Expresión de evaluación y análisis sintáctico Se calcula empleando la notación polaca inversa utilizan- do una estructura de pila para los posibles valores. Las expresiones pueden ser representadas en prefijo, infijo, postfijo. La conversión de una forma de la expresión a otra forma necesita de una pila. Muchos compiladores utilizan una pila para analizar la sintaxis de las expresio- nes, bloques de programa, etc. Antes de traducir el código de bajo nivel. La mayoría de los lenguajes de programa- ción son de contexto libre de los idiomas que les permite ser analizados con máquinas basadas en la pila. Por ejemplo, el cálculo: ((1 + 2) * 4) + 3, puede ser ano- tado como en notación postfija con la ventaja de no pre- valecer las normas y los paréntesis necesario: 1 2 + 4 * 3 + La expresión es evaluada de izquierda a derecha utilizan- do una pila: • Apilar cuando se enfrentan a un operando y • Desafilar dos operandos y evaluar el valor cuando se enfrentan a una operación. • Apilar el resultado. De la siguiente manera (la Pila se muestra después de que la operación se haya llevado a cabo): ENTRADA OPERACIÓN PILA 1 Apilar operando 1 2 Apilar operando 1, 2 + Añadir 3 4 Apilar operando 3, 4 * Multiplicar 12 3 Apilar operando 12, 3 + Añadir 15 El resultado final, 15, se encuentra en la parte superior de la pila al final del cálculo.
  • 43.
    10.8. SEGURIDAD 37 10.7.1Tiempo de ejecución de la gestión de memoria Artículo principal: Pila basada en la asignación de memo- ria y Pila máquina. Una serie de lenguajes de programa- ción están orientadas a la pila, lo que significa que la ma- yoría definen operaciones básicas (añadir dos números, la impresión de un carácter) cogiendo sus argumentos de la pila, y realizando de nuevo los valores de retorno en la pi- la. Por ejemplo, PostScript tiene una pila de retorno y un operando de pila, y también tiene un montón de gráficos estado y un diccionario de pila. Forth utiliza dos pilas, una para pasar argumentos y una subrutina de direcciones de retorno. El uso de una pila de retorno es muy común, pero el uso poco habitual de un argumento para una pila legible para humanos es el lenguaje de programación Forth razón que se denomina una pila basada en el idioma. Muchas máquinas virtuales también están orientadas ha- cia la pila, incluida la p-código máquina y la máquina vir- tual Java. Casi todos los entornos de computación de tiempo de eje- cución de memoria utilizan una pila especial PILA para tener información sobre la llamada de un procedimiento o función y de la anidación con el fin de cambiar al contexto de la llamada a restaurar cuando la llamada termina. Ellos siguen un protocolo de tiempo de ejecución entre el que llama y el llamado para guardar los argumentos y el valor de retorno en la pila. Pila es una forma importante de apo- yar llamadas anidadas o a funciones recursivas. Este tipo de pila se utiliza implícitamente por el compilador para apoyar CALL y RETURN estados (o sus equivalentes), y no es manipulada directamente por el programador. Algunos lenguajes de programación utilizar la pila para almacenar datos que son locales a un procedimiento. El espacio para los datos locales se asigna a los temas de la pila cuando el procedimiento se introduce, y son borradas cuando el procedimiento termina. El lenguaje de progra- mación C es generalmente aplicado de esta manera. Uti- lizando la misma pila de los datos y llamadas de proce- dimiento tiene importantes consecuencias para la segu- ridad (ver más abajo), de los que un programador debe ser consciente, a fin de evitar la introducción de graves errores de seguridad en un programa. 10.7.2 Solucionar problemas de búsqueda La búsqueda de la solución de un problema, es indepen- dientemente de si el enfoque es exhaustivo u óptimo, ne- cesita espacio en la pila. Ejemplos de búsqueda exhaus- tiva métodos son fuerza bruta y backtraking. Ejemplos de búsqueda óptima a explorar métodos,son branch and bound y soluciones heurísticas. Todos estos algoritmos utilizan pilas para recordar la búsqueda de nodos que se han observado, pero no explorados aún. La única alter- nativa al uso de una pila es utilizar la recursividad y de- jar que el compilador sea recursivo (pero en este caso el compilador todavía está utilizando una pila interna). El uso de pilas es frecuente en muchos problemas, que van desde almacenar la profundidad de los árboles hasta re- solver crucigramas o jugar al ajedrez por ordenador. Al- gunos de estos problemas pueden ser resueltos por otras estructuras de datos como una cola. 10.8 Seguridad La seguridad a la hora de desarrollar software usando es- tructuras de datos de tipo pila es un factor a tener en cuen- ta debido a ciertas vulnerabilidades que un uso incorrecto de éstas puede originar en la seguridad de nuestro soft- ware o en la seguridad del propio sistema que lo ejecu- ta. Por ejemplo, algunos lenguajes de programación usan una misma pila para almacenar los datos para un proce- dimiento y el enlace que permite retornar a su invocador. Esto significa que el programa introduce y extrae los da- tos de la misma pila en la que se encuentra la información crítica con las direcciones de retorno de las llamadas a procedimiento, supongamos que al introducir datos en la pila lo hacemos en una posición errónea de manera que introducimos datos de mayor tamaño al soportado por la pila corrompiendo así las llamadas a procedimientos, pro- vocaríamos un fallo en nuestro programa. Ésta técnica usada de forma maliciosa (es similar, pero en otro ámbi- to al buffer overflow) permitiría a un atacante modificar el funcionamiento normal de nuestro programa y nuestro sistema, y es al menos una técnica útil si no lo evitamos en lenguajes muy populares como el ejemplo C++. 10.9 Véase también • Listas • Pilas Acotadas • Colas 10.10 Enlaces externos • Estructuras de datos/Pilas y colas, en Wikibooks (inglés) • Distintas implementaciones del manejo de pilas en RosettaCode.org
  • 44.
    Capítulo 11 Programa informático Unprograma informático escrito en un estilo orientado a objetos. Un programa informático o programa de compu- tadora es una secuencia de instrucciones, escritas pa- ra realizar una tarea específica en una computadora.[1] Este dispositivo requiere programas para funcionar, por lo general ejecutando las instrucciones del programa en un procesador central.[2] El programa tiene un forma- to ejecutable que la computadora puede utilizar directa- mente para ejecutar las instrucciones. El mismo progra- ma en su formato de código fuente legible para huma- nos, del cual se derivan los programas ejecutables (por ejemplo, compilados), le permite a un programador estu- diar y desarrollar sus algoritmos. Una colección de pro- gramas de computadora y datos relacionados se conoce como software. Generalmente el código fuente lo escriben profesionales conocidos como programadores de computadora.[3] Es- te código se escribe en un lenguaje de programación que sigue uno de los siguientes dos paradigmas: imperativo o declarativo, y que posteriormente puede ser converti- do en un archivo ejecutable (usualmente llamado un pro- grama ejecutable o un binario) por un compilador y más tarde ejecutado por una unidad central de procesamien- to. Por otra parte, los programas de computadora se pue- den ejecutar con la ayuda de un intérprete, o pueden ser empotrados directamente en hardware. De acuerdo a sus funciones, los programas informáti- cos se clasifican en software de sistema y software de apli- cación. En las computadoras actuales, al hecho de ejecu- tar varios programas de forma simultánea y eficiente, se le conoce como multitarea. 11.1 Programación La programación de computadoras es el proceso iterati- vo de escribir o editar código fuente. Dicha edición de código fuente implica probar, analizar y perfeccionar, y, a veces, coordinar con otros programadores, en el caso de un programa desarrollado en conjunto. Una persona que practica esta técnica se le conoce como programador de computadoras, desarrollador de software, o codifica- dor. El proceso, a veces a largo plazo, de programación de computadoras normalmente se lo conoce como desarrollo de software. El término ingeniería de software se está convirtiendo en muy popular, ya que esta actividad es vis- ta como una disciplina de ingeniería. 11.1.1 Paradigmas Los programas de ordenador se pueden clasificar según el paradigma del lenguaje de programación utilizado pa- ra producirlos. Dos de los principales paradigmas son imperativos y declarativos. Los programas escritos con un lenguaje imperativo espe- cifican un algoritmo utilizando declaraciones, expresio- nes e informes.[4] Una declaración asocia un nombre de variable a un tipo de datos. Por ejemplo: var x: integer; . Una expresión produce un valor. Por ejemplo: 2 + 2 pro- duce 4. Por último, una declaración puede asignar una expresión a una variable o usar el valor de una variable para alterar las estructuras de control del programa. Por ejemplo: x := 2 + 2; if x = 4 then hacer_algo(); Una crí- tica de los lenguajes imperativos es el efecto secundario de una sentencia de asignación en una clase de variables llamadas variables no locales.[5] 38
  • 45.
    11.2. EJECUCIÓN YALMACENAMIENTO DE LOS PROGRAMAS 39 Los programas escritos en un lenguaje declarativo espe- cifican las propiedades que tienen o que deben cumplir- se para la salida. No especifican detalles expresados en términos de flujo de control de la máquina de ejecución pero sí de las relaciones matemáticas entre los objetos declarados y sus propiedades. Los lenguajes funcionales y lógicos son dos amplias categorías de lenguajes decla- rativos. El principio detrás de los lenguajes funcionales (como Haskell) es el de no permitir efectos secundarios, lo que hace que sea más fácil para razonar sobre los pro- gramas como si se tratasen de funciones matemáticas.[5] El principio detrás de los lenguajes lógicos (como Prolog) es definir el problema a ser resuelto - la meta - y dejar la solución detallada al propio sistema Prolog.[6] El objetivo se define proporcionando la lista de sub-objetivos. Luego, cada subobjetivo se define más arriba, proporcionando la lista de sus sub-objetivos, etc. Si la ruta de sub-objetivos no encuentra una solución, entonces ese subobjetivo se retrocede y otra vía se intenta sistemáticamente. La forma en que se crea el programa puede ser textual o visual. En un programa de lenguaje visual, los elementos en vez de ser textualmente especificados son manipulados gráficamente. 11.1.2 Compilado o interpretando Un programa de computadora bajo la forma de lengua- je de programación de computadoras legible por un hu- mano, se lo llama código fuente. Dicho código fuen- te se puede convertir en una imagen ejecutable por un compilador o ejecutarse inmediatamente con la ayuda de un intérprete. Cualquiera de los programas compilados o interpretados pueden ser ejecutados en un proceso por lotes sin inter- vención humana, pero los programas interpretados le per- miten al usuario escribir comandos en una sesión interac- tiva. En este caso, los programas son los comandos sepa- rados, cuya ejecución se produce secuencialmente, y por lo tanto simultáneamente. Cuando se utiliza un lenguaje para dar órdenes a una aplicación de software (como un shell de Unix u otra interfaz de línea de comandos), se le llama un lenguaje de scripts. Los compiladores se utilizan para traducir el código fuen- te de un lenguaje de programación, ya sea en código obje- to o código máquina.[7] El código objeto de objeto nece- sita procesamiento adicional para convertirse en código máquina, y el código máquina es el código nativo de la unidad central de procesamiento, listo para su ejecución. Los programas de computadora compilados se conocen comúnmente como ejecutables, imágenes binarias, o sim- plemente como binarios — una referencia al formato de archivo binario utilizado para almacenar el código ejecu- table. Los programas de computadora — interpretados en un lo- te o una sesión interactiva — o bien se descodifican y lue- go ejecutados inmediatamente o se decodifican en alguna representación intermedia eficiente para la ejecución fu- tura. BASIC, Perl y Python son ejemplos de programas de computadora ejecutados inmediatamente. Por otra parte, los programas de computadora de Java se compilan antes de tiempo y se almacena como un código independien- te de la máquina llamado bytecode. Entonces, dicho by- tecode es ejecutado a petición de un intérprete llamado máquina virtual. La principal desventaja de los intérpretes es que los pro- gramas de computadora corren más lento que cuando son compilados. La interpretación de código resulta más lenta que la ejecución de la versión compilada porque el intér- prete debe decodificar cada declaración cada vez que se carga y luego realizar la acción deseada. Sin embargo, el desarrollo de software puede ser más rápido usando un in- térprete porque la prueba es inmediata cuando se omite el paso de la compilación. Otra desventaja de los intérpretes es que debe estar presente al menos uno en la computado- ra durante la ejecución del programa de computadora. Por el contrario, los programas de computadora compilados no necesitan compilador presente durante la ejecución. No se requieren propiedades de un lenguaje de progra- mación si se está compilado exclusivamente o interpre- tándose exclusivamente. Por lo general, la clasificación refleja el método más popular de ejecución del lenguaje. Por ejemplo, BASIC se considera un lenguaje interpreta- do y C un lenguaje compilado, a pesar de la existencia de compiladores de BASIC e intérpretes de C. Algunos sis- temas utilizan compilación en tiempo de ejecución (JIT) mediante la cual las secciones de la fuente se compilan 'sobre la marcha' y se almacenan para ejecuciones poste- riores. 11.1.3 Programas que se auto-modifican Un programa informático en ejecución normalmente es tratado como algo diferente de los datos con los cuales opera. Sin embargo, en algunos casos ésta distinción es ambigua, especialmente cuando un programa se modi- fica a sí mismo. El programa modificado es secuencial- mente ejecutado como parte del mismo programa. El có- digo que se auto-modifica es posible para programas es- critos en código máquina, Lenguaje ensamblador, Lisp, C, COBOL, PL/1 y Prolog y JavaScript (la función eval), entre otros. 11.2 Ejecución y almacenamiento de los programas Típicamente, los programas se almacenan en una memoria no volátil (por ejemplo un disco), para que luego el usuario de la computadora, directa o indirectamente, solicite su ejecución. Al momento de dicha solicitud, el programa es cargado en la memoria de acceso aleatorio
  • 46.
    40 CAPÍTULO 11.PROGRAMA INFORMÁTICO o RAM del equipo, bajo el control del software llama- do sistema operativo, el cual puede acceder directamente al procesador. El procesador ejecuta (corre) el programa, instrucción por instrucción hasta que termina. A un pro- grama en ejecución se le suele llamar también proceso. Un programa puede terminar su ejecución en forma nor- mal o por causa de un error, dicho error puede ser de software o de hardware. 11.2.1 Programas empotrados en hardwa- re El microcontrolador a la derecha de la Memoria USB está con- trolada por un firmware empotrado. Algunos programas están empotrados en el hardware. Una computadora con arquitectura de programas alma- cenados requiere un programa inicial almacenado en su ROM para arrancar. El proceso de arranque es para iden- tificar e inicializar todos los aspectos del sistema, desde los registros del procesador, controladores de dispositi- vos hasta el contenido de la memoria RAM.[8] Seguido del proceso de inicialización, este programa inicial carga al sistema operativo e inicializa al contador de programa para empezar las operaciones normales. Independiente de la computadora, un dispositivo de hardware podría tener firmware empotrado para el control de sus operaciones. El firmware se utiliza cuando se espera que el programa cambie en raras ocasiones o nunca, o cuando el programa no debe perderse cuando haya ausencia de energía.[9] 11.2.2 Programas cargados manualmente Los programas históricamente se cargaron manualmen- te al procesador central mediante interruptores. Una ins- trucción era representada por una configuración de es- tado abierto o cerrado de los interruptores. Después de establecer la configuración, se ejecutaba un botón de eje- cución. Este proceso era repetitivo. También, histórica- mente los programas se cargaban manualmente median- te una cinta de papel o tarjetas perforadas. Después de que el programa se cargaba, la dirección de inicio se es- Interruptores para la carga manual en una Data General Nova 3. tablecía mediante interruptores y el botón de ejecución se presionaba.[10] 11.2.3 Programas generados automática- mente La programación automática es un estilo de programación que crea código fuente mediante clases genéricas, prototipos, plantillas, aspectos, y generadores de código para aumentar la productivi- dad del programador. El código fuente se genera con herramientas de programación tal como un procesador de plantilla o un IDE. La forma más simple de un generador de código fuente es un procesador macro, tal como el preprocesador de C, que reemplaza patrones de código fuente de acuerdo a reglas relativamente simples. Un motor de software da de salida código fuente o lenguaje de marcado que simultáneamente se vuelve la entrada de otro proceso informático. Podemos pen- sar como analogía un proceso manejando a otro sien- do el código máquina quemado como combustible. Los servidores de aplicaciones son motores de software que entregan aplicaciones a computadoras cliente. Por ejem- plo, un software para wikis es un sevidor de aplicacio- nes que permite a los usuarios desarrollar contenido di- námico ensamblado a partir de artículos. Las Wikis ge- neran HTML, CSS, Java, y Javascript los cuales son interpretados por un navegador web. 11.2.4 Ejecución simultánea Muchos programas pueden correr simultáneamente en la misma computadora, a lo cual se le conoce como multitarea y puede lograrse a través de mecanismos de software o de hardware. Los sistemas operativos mo- dernos pueden correr varios programas a través del planificador de procesos — un mecanismo de software para conmutar con frecuencia la cantidad de procesos del procesador de modo que los usuarios puedan interactuar con cada programa mientras estos están corriendo.[11]
  • 47.
    11.6. BIBLIOGRAFÍA 41 Tambiénse puede lograr la multitarea por medio del hardware; las computadoras modernas que usan varios procesadores o procesadores con varios núcleos pueden correr muchos programas a la vez.[12] 11.3 Categorías funcionales Los programas se pueden categorizar según líneas funcio- nales. Estas categorías funcionales son software de sis- tema y software de aplicación. El software de sistema incluye al sistema operativo el cual acopla el hardware con el software de aplicación.[13] El propósito del siste- ma operativo es proveer un ambiente en el cual el soft- ware de aplicación se ejecuta de una manera conveniente y eficiente.[13] Además del sistema operativo, el softwa- re de sistema incluye programas utilitarios que ayudan a manejar y configurar la computadora. Si un programa no es software de sistema entonces es software de aplicación. El middleware también es un software de aplicación que acopla el software de sistema con la interfaz de usuario. También son software de aplicación los programas utili- tarios que ayudan a los usuarios a resolver problemas de aplicaciones, como por ejemplo la necesidad de ordena- miento. 11.4 Véase también • Algoritmo para la relación entre los programas in- formáticos y algoritmos • Estructura de datos • Archivo cabra para un tipo específico de programa informático utilizado solo para liberar y estudiar los efectos de virus informáticos en los sistemas físicos y virtuales • Inteligencia artificial • Sistema multi-agente • Aplicaciones informáticas 11.5 Referencias [1] Stair, Ralph M., et al. (2003). Principles of Information Systems, Sixth Edition (en inglés). Thomson Learning, Inc. p. 132. ISBN 0-619-06489-7. [2] Silberschatz, Abraham (1994). Operating System Con- cepts, Fourth Edition (en inglés). Addison-Wesley. p. 58. ISBN 0-201-50480-4. [3] «Algorithms and Computer Programming» (en inglés). Consultado el 8 de setiembre de 2014. [4] Wilson, Leslie B. (1993). Comparative Programming Lan- guages, Second Edition (en inglés). Addison-Wesley. p. 75. ISBN 0-201-56885-3. [5] Wilson, Leslie B. (1993). Comparative Programming Lan- guages, Second Edition (en inglés). Addison-Wesley. p. 213. ISBN 0-201-56885-3. [6] Wilson, Leslie B. (1993). Comparative Programming Lan- guages, Second Edition (en inglés). Addison-Wesley. p. 244. ISBN 0-201-56885-3. [7] «What is a Compiler?» (en inglés). Consultado el 10 de enero de 2012. [8] Silberschatz, Abraham (1994). Operating System Con- cepts, Fourth Edition (en inglés). Addison-Wesley. p. 30. ISBN 0-201-50480-4. [9] Tanenbaum, Andrew S. (1990). Structured Computer Or- ganization, Third Edition. Prentice Hall. p. 11. ISBN 0- 13-854662-2. (en inglés). [10] Silberschatz, Abraham (1994). Operating System Con- cepts, Fourth Edition (en inglés). Addison-Wesley. p. 6. ISBN 0-201-50480-4. [11] Silberschatz, Abraham (1994). Operating System Con- cepts, Fourth Edition (en inglés). Addison-Wesley. p. 100. ISBN 0-201-50480-4. [12] Akhter, Shameem (2006). Multi-Core Programming. Ri- chard Bowles (Intel Press). pp. 11–13. ISBN 0-9764832- 4-6. (en inglés). [13] Silberschatz, Abraham (1994). Operating System Con- cepts, Fourth Edition (en inglés). Addison-Wesley. p. 1. ISBN 0-201-50480-4. 11.6 Bibliografía • Knuth, Donald E. (1997). The Art of Computer Pro- gramming, Volume 1, 3rd Edition (en inglés). Bos- ton: Addison-Wesley. ISBN 0-201-89683-4. • Knuth, Donald E. (1997). The Art of Computer Pro- gramming, Volume 2, 3rd Edition (en inglés). Bos- ton: Addison-Wesley. ISBN 0-201-89684-2. • Knuth, Donald E. (1997). The Art of Computer Pro- gramming, Volume 3, 3rd Edition (en inglés). Bos- ton: Addison-Wesley. ISBN 0-201-89685-0. 11.7 Enlaces externos • Definición de “Programa” en Webopedia (en inglés) • Definición de “Computer Program” en dictio- nary.com (en inglés)
  • 48.
    42 CAPÍTULO 11.PROGRAMA INFORMÁTICO • Esta obra deriva de la traducción total de Computer program de Wikipedia en inglés, concretamente de esta versión, publicada por sus editores ba- jo la Licencia de documentación libre de GNU y la Licencia Creative Commons Atribución- CompartirIgual 3.0 Unported.
  • 49.
    11.8. TEXT ANDIMAGE SOURCES, CONTRIBUTORS, AND LICENSES 43 11.8 Text and image sources, contributors, and licenses 11.8.1 Text • Computadora Fuente: http://es.wikipedia.org/wiki/Computadora?oldid=81730079 Colaboradores: PACO, Joseaperez, Srtxg, Oblongo, Moriel, Sauron, JorgeGG, Digital-h, Pieter, AlexAlonso, Mxn, Wesisnay, Lourdes Cardenal, Hashar, ManuelGR, Julie, Robbot, Angus, Mdiagom, Vivero, Zwobot, Comae, Paz.ar, Drjackzon, Rosarino, Dodo, Pybalo, Wikilibrarian~eswiki, Felipe.bachomo, Sms, Avm, Tos- tadora, Tano4595, Jarfil, Robotito, Enric Naval, Carlos Quesada~eswiki, Dianai, Triebjlr, Pablomdo, Cinabrium, Porao, Trylks, Evi- llan~eswiki, 142857, Vizcarra~eswiki, Ecemaml, Kordas, Padeleti, Elsenyor, Niqueco, Renabot, Richy, FAR, Supersouissi, Javierme, Reignerok, Digigalos, Taragui, Sonett72~eswiki, Boticario, Deleatur, Soulreaper, Petronas, Orgullomoore, Pencho15, Airunp, JMPerez, Edub, Klemen Kocjancic, Yrithinnd, Taichi, Emijrp, Rembiapo pohyiete (bot), Gussisaurio, Wikiseldon, Magister Mathematicae, Kokoo, RedTony, Ericbaez, Goofys, Orgullobot~eswiki, RobotQuistnix, Byj2000, Platonides, Itnas19, Veltys, Alhen, Superzerocool, Chobot, San- cebau, Deprieto, Yrbot, Amadís, BOT-Superzerocool, Dagavi, Oscar ., FlaBot, Varano, Vitamine, .Sergio, Dangarcia, Mortadelo2005, Juan.res~eswiki, Museo8bits, Olea, GermanX, Lin linao, Equi, Zam, Willtron, Unaiaia, Armin76, Gaijin, The Photographer, Jesuja, Tiger- fenix, Santiperez, Txo, Leitzaran, HECTOR ARTURO AZUZ SANCHEZ, Banfield, CHV, JanoMasoneria, Milestones, José., Maldoror, Er Komandante, Tomatejc, Jarke, EOZyo, Siabef, Folkvanger, Makahaxi, The worst user, Tafol, Zand, BOTpolicia, Reynaldo Villegas Pe- ña, Alfa989, Gizmo II, CEM-bot, Jorgelrm, Gabriel Acquistapace, Laura Fiorucci, Pinar~eswiki, Heavyrock, Nagul, Roblespepe, Ignacio Icke, Durero, Jjvaca, Mrjoui, Pacostein, Baiji, Roberpl, Rastrojo, Dantadd, Antur, Patori, Willicab, Eledwin01, Jjafjjaf, Gafotas, Progra- mador, Dorieo, Montgomery, FrancoGG, Resped, Thijs!bot, Persona~eswiki, Xoacas, Frankcu, Ricardoramirezj, Tortillovsky, Mahadeva, Bot que revierte, Escarbot, Kommodin, RoyFocker, Ángel Luis Alfaro, Albireo3000, Will vm, PhJ, Ranf, Botones, Cratón, Isha, Jdvilla- lobos, Kenbill, Tarantino, Chuck es dios, Hanjin, Dogor, Góngora, Artaris, JAnDbot, Darolu, Jugones55, Casamanita, VanKleinen, Kved, DerHexer, Praedos, Mansoncc, Satin, Marinna, Muro de Aguas, Xavigivax, CommonsDelinker, TXiKiBoT, FeKuLa, Cronos x, Jdiezchica, Bot-Schafter, Gacq, Humberto, Netito777, HAMM, Rodgarcia, Camilogalactico, Amanuense, Pedro Nonualco, Chabbot, MotherForker, Idioma-bot, Qoan, Pólux, BL, Jmvkrecords, Developer, Jesus 2003 18 x, Vtornet, Manuel Trujillo Berges, Jtico, Kzman, Avsurrutia, Biaso- li, Bucephala, AlnoktaBOT, Yio, Cinevoro, Exitocoastal, VolkovBot, Jurock, Snakeyes, Technopat, C'est moi, Queninosta, Penarc, Chixpy, Libertad y Saber, Penguino, Josell2, Matdrodes, Ghsus, Fernando Estel, Elabra sanchez, Synthebot, KLosma, BlackBeast, Shooke, Lucien leGrey, Netmaster123, Vatelys, AlleborgoBot, Zaca83, Vladimir138, Chicano~eswiki, Muro Bot, Edmenb, Komputisto, Bucho, Racso, YonaBot, BotMultichill, Gerakibot, SieBot, Mushii, Ctrl Z, Naitsirk, Loveless, Macarrones, Rimac, El duende alegre, Carmin, Pompilio Zigrino, Cobalttempest, OLM, Rigenea, Chrihern, Drinibot, Rodolfoap, Bigsus-bot, BOTarate, Wiljoel, STBot~eswiki, Mel 23, Manwë, Pascow, Correogsk, Chino-akd, Garber, Greek, Elmascapodetodos, BuenaGente, Mazzuccoxp, Aleposta, Mafores, PipepBot, Chico512, Ivanics, Tirithel, Mutari, Locos epraix, robot, Superzambo, Montehermoso-spain, Javierito92, Marcecoro, HUB, Antón Francho, Rodrigofeu, Nicop, DragonBot, JOKblogger, McMalamute, Eduardosalg, Cristinita19, P4K1T0, John.007, Qwertymith, EdgarGSX, Leon- polanco, Pan con queso, Alejandroml, Alejandrocaro35, LuisArmandoRasteletti, Furti, Cayosama, Pene255, Poco a poco, BetoCG, Lloyd- 02, Rαge, Açipni-Lovrij, Nepenthes, Rodog, Hierro duro, Porromaligno10, UA31, Waldner~eswiki, SergioN, MARC912374, AVBOT, David0811, Jorghex, LucienBOT, A ver, Louperibot, Hemingway10, Angel GN, Ponchoperez, Joan231, Carlos A. Baez, Diegusjaimes, Davidgutierrezalvarez, MelancholieBot, Linfocito B, Rezagos, Manuelito.angelito, Danitza iveth, Miguelpab, CarsracBot, JohnManuel, Parra christopher, Arjuno3, Lucas dicci, Andreasmperu, Dalton2, Ramon00, ASPARTAME, Jotterbot, Bucle, Ixfd64, Tauro1990, Elec- trodan, Dangelin5, Joseagrc, Yodigo, Barteik, Koj, Oskar105, Isah213, Juanangeles55, Hampcky, Shekatsu8er, Oodrap, Vivaelcelta, Nixón, ArthurBot, Diogeneselcinico42, ChristianH, Manuelt15, Xqbot, Simeón el Loco, Jkbw, SassoBot, Dreitmen, Jandres95, Maron siglos15, Enrique Consultas, FrescoBot, Ricardogpn, Jvv110687, Lauragaribaldi, Olga Atzimba, Igna, Javier Castaneda, MauritsBot, Kroci, Tobe- Bot, PDD20, Zenapau, Vubo, DixonDBot, Andersonpana31, Abece, Lungo, Wikipedico wikipedico, Fitoschido, Clesmery, TorQue Astur, Steveen777, Jembot, PatruBOT, Beatriz taboas, Cesar Eduardo Ballesteros Aguirre, KamikazeBot, Xitlalimons, Almiux2009, Angelito7, TjBot, Ripchip Bot, Olivares86, Tarawa1943, Jorge c2010, Foundling, Wikiléptico, Axvolution, P. S. F. Freitas, Velual, EmausBot, Savh, AVIADOR, ZéroBot, HRoestBot, ChessBOT, Sergio Andres Segovia, ChuispastonBot, Cedecomsa, MadriCR, WikitanvirBot, Mjbmrbot, Movses-bot, Astronomo solar, Betostw, Metrónomo, El magio12, MerlIwBot, KLBot2, Vagobot, Sebrev, MetroBot, Invadibot, Nernix1, Acratta, LlamaAl, Santga, Akdkiller, Jpyamamoto09, MaKiNeoH, Legobot, Addbot, Balles2601, Nación del fuego100, TheDarkGosht, Toniperis, Rsniaza, Sintaxis Sintáctico, JacobRodrigues, Ffranciscovegav, Minasadaft, Ivan giovani silva palafox, Guayo1300, Josesuazoo, Gavillas, UMIdani, BY THE, Gddgd, Timohap, MrCharro, Jarould, Crystallizedcarbon, Pipemancini, Boloni14, Chovichovy, Luis felipe martinez sanchez, Dfcordoba, Pinkilurulu, Domyalatorre, Maribel001, BenjaBot y Anónimos: 1133 • Ciencias de la información (tecnología) Fuente: http://es.wikipedia.org/wiki/Ciencias%20de%20la%20informaci%C3%B3n% 20(tecnolog%C3%ADa)?oldid=80271027 Colaboradores: Trylks, Eloy, Tamorlan, CEM-bot, Davius, Ángel Luis Alfaro, Serg!o, NaBUru38, Technopat, Kavor, Ruud Koot, SuperBraulio13, Canyq, Waeswaes, Grillitus, El Ayudante, ConnieGB y Anónimos: 9 • Lenguaje de programación Fuente: http://es.wikipedia.org/wiki/Lenguaje%20de%20programaci%C3%B3n?oldid=81986369 Colabo- radores: AstroNomo, Carlita~eswiki, Nnss, Joseaperez, Moriel, Sauron, JorgeGG, ManuelGR, Julie, Angus, Rumpelstiltskin, Achury, San- bec, Zwobot, Javier Carro, Scott MacLean, MiguelRdz, Dodo, Triku, Ascánder, Avm, Rsg, HHM, Cookie, Tostadora, Elwikipedista, Da- nakil~eswiki, Murphy era un optimista, Jsanchezes, Jarfil, Elproferoman, Melocoton, Kalcetin, Porao, Trylks, Almorca, Suruena, Balderai, Dat, Niqueco, ZackBsAs, Ilario, LeonardoRob0t, Digigalos, Zeioth, Soulreaper, AlfonsoERomero, Airunp, JMPerez, Edub, Taichi, Rem- biapo pohyiete (bot), Genba, Magister Mathematicae, Aadrover, Orgullobot~eswiki, RobotQuistnix, Gcsantiago, Platonides, Unf, LarA, Alhen, Superzerocool, Chobot, Yrbot, BOT-Superzerocool, Oscar ., Martincarr, Vitamine, Cesarsorm, Wiki-Bot, Icvav, GermanX, Aalva- radoH, Indu~eswiki, KnightRider, Jesuja, Tigerfenix, Santiperez, PabloBD, Banfield, Otermin, Nowadays, Er Komandante, Spc, Tomatejc, Balix, Rbonvall, Jorgechp, Juanjo64, BOTpolicia, Qwertyytrewqqwerty, Chfiguer, CEM-bot, Jorgelrm, Krli2s, Spazer, Alex15090, Xemuj, Ignacio Icke, Retama, Baiji, Ezequiel3E, Osepu, Roberpl, JoRgE-1987, Eamezaga, Antur, Mr. Moonlight, FrancoGG, Fsd141, Juank8041, Alvaro qc, Srengel, Cansado, Mahadeva, Rata blanca, Diosa, Escarbot, RoyFocker, Eduiba, IrwinSantos, Will vm, Tintinando, Botones, Cra- tón, Isha, Arcibel, Mpeinadopa, JAnDbot, Thormaster, Jugones55, BelegDraug, Diego.souto, Kved, TitoPeru, Mansoncc, BetBot~eswiki, Xavigivax, Danielantonionunez, Bot-Schafter, Elisardojm, Humberto, Netito777, Amanuense, Bedwyr, Idioma-bot, Pólux, Sebado, Bu- cephala, AlnoktaBOT, Dusan, Cinevoro, VolkovBot, Carola-zzz, Snakeyes, Technopat, Galandil, Queninosta, Aliamondano, Pejeyo, Mat- drodes, Elabra sanchez, Synthebot, House, DJ Nietzsche, Gorpik, Lucien leGrey, AlleborgoBot, Gmarinp, IIM 78, Muro Bot, Edmenb, J.M.Domingo, Komputisto, Bucho, SieBot, Mushii, Danielba894, Carlos Zeas, Cobalttempest, Rigenea, Hompis, Drinibot, Bigsus-bot, IsmaelLuceno, Mel 23, Manwë, Correogsk, Greek, Joseromerogc, BuenaGente, Mafores, Cam367, Tirithel, Jarisleif, Javierito92, HUB, FCPB, Eduardosalg, Edgarchan, Leonpolanco, Pan con queso, Alecs.bot, LordT, Descansatore, Petruss, Poco a poco, Juan Mayordomo, Darkicebot, Rαge, MADAFACK, Frei sein, Raulshc, Açipni-Lovrij, Majin boo, Camilo, UA31, Inakivk, Esterdelakpaz, CharlesKnight, AVBOT, Swatnio, DayL6, David0811, J.delanoy, MarcoAurelio, JyQ, Ezarate, Diegusjaimes, MelancholieBot, Linfocito B, Sebasweee,
  • 50.
    44 CAPÍTULO 11.PROGRAMA INFORMÁTICO Arjuno3, Andreasmperu, Luckas-bot, MystBot, Bob A, Roinpa, Jotterbot, Sappler, Akhran, Vic Fede, Barteik, Billinghurst, Vandal Crus- her, Julio Cardmat, XZeroBot, ArthurBot, Argentinoo, Jefrcast, SuperBraulio13, Ortisa, Manuelt15, Xqbot, Jkbw, SassoBot, Dreitmen, Ricardogpn, Igna, Torrente, Adryitan, Botarel, MauritsBot, Googolplanck, Hprmedina, TobeBot, Execoot~eswiki, Palita1880, Halfdrag, Vubo, YSCO, PatruBOT, Ganímedes, Angelito7, Mr.Ajedrez, Jose1080i, Humbefa, Tarawa1943, Jorge c2010, GrouchoBot, Cesarintel, Miss Manzana, Jose1100000, Edslov, EmausBot, Savh, AVIADOR, Ingenieros instructivos, HRoestBot, Allforrous, Sergio Andres Sego- via, Chope777, Rubpe19, Eroyuela, ChuispastonBot, MadriCR, Waka Waka, Cordwainer, Lcsrns, Antonorsi, Valthern, Edc.Edc, Ismaell, Jicapter, Sebrev, MetroBot, Sansgumen, Mascorria, Teclis jma, Gusama Romero, Nernix1, Acratta, Johnbot, Harpagornis, LlamaAl, Helmy oved, Erandly, Flashlack, Cyrax, Napier, Ralgisbot, Syum90, Fabrizotus, BLACK M0NST3R, Juanitoalcachofados, Addbot, Shinigamisa- jayin, Balles2601, Killtas, Patoogalvan, Davidpaisa04, DarkBlueZV, Equiz yolo swaw, Jarould, Matiia, Egis57, Geekisthebest1, Ximenacs y Anónimos: 809 • Algoritmo Fuente: http://es.wikipedia.org/wiki/Algoritmo?oldid=81963760 Colaboradores: Llull~eswiki, Pit~eswiki, Sabbut, Moriel, Sau- ron, JorgeGG, Lourdes Cardenal, ManuelGR, Julie, Angus, Vivero, Riviera, Rosarino, Dodo, Ejmeza, Crescent Moon, Triku, Sms, Rsg, Tostadora, Elwikipedista, Tano4595, Jsanchezes, Ríos-Ortega, JAAC, Jecanre, Cinabrium, Schummy, Huhsunqu, Balderai, Ecemaml, Re- nabot, FAR, Ictlogist, Boticario, Soulreaper, Orgullomoore, AlfonsoERomero, Airunp, JMPerez, Edub, Yrithinnd, Taichi, Emijrp, Rem- biapo pohyiete (bot), Caiser, Magister Mathematicae, RobotQuistnix, Alhen, Superzerocool, Chobot, Dromero, Sancebau, Yrbot, Amadís, FlaBot, Vitamine, .Sergio, YurikBot, Mortadelo2005, GermanX, Zam, Willtron, KnightRider, The Photographer, YoaR, Gothmog, No sé qué nick poner, Carutsu, C-3POrao, Jesuja, Banfield, Maldoror, Er Komandante, Camima, Haitike, KocjoBot~eswiki, Tomatejc, Jarke, Paintman, Rbonvall, Kn, Aleator, Jstitch, BOTpolicia, Gizmo II, CEM-bot, Jorgeu, Jorgelrm, Laura Fiorucci, Kojie, -jem-, Alexav8, Ignacio Icke, Efegé, Retama, AlphaWiki~eswiki, Baiji, Bot~eswiki, Antur, Dorieo, Ingenioso Hidalgo, Fsd141, AlbertMA, Thijs!bot, Xxim, Alvaro qc, Escarbot, Yeza, Zupez zeta, Drake 81, RoyFocker, Ninovolador, MorZilla, Cratón, Isha, Dogor, Gusgus, Obueno, JAnDbot, Jugones55, JuanRodríguez, Kved, DerHexer, Lecuona, Mansoncc, Muro de Aguas, Xavigivax, TXiKiBoT, S3v3r-1, Elisardojm, Humberto, Netito777, Sophie kowalsky, AS990, ZrzlKing, Chabbot, Pólux, Bucephala, AchedDamiman, VolkovBot, Snakeyes, Technopat, Queninosta, Rays- torm, Libertad y Saber, Matdrodes, Elabra sanchez, Synthebot, DJ Nietzsche, BlackBeast, Shooke, AlleborgoBot, Muro Bot, Peregring-lk, Clarad, Komputisto, MiguelAngel fotografo, SieBot, Aitorzubiaurre, Danielba894, Ctrl Z, Francisco Mochis, Carmin, Rigenea, Drinibot, CASF, BOTarate, Arlm1, Fide07, STBot~eswiki, Mel 23, Guillervf91, Manwë, Fegc77, Greek, H3r3dia, BuenaGente, Qix~eswiki, Relleu, PipepBot, Fadesga, Chuchot, Tirithel, Mutari, XalD, robot, Jarisleif, Javierito92, HUB, PeruProfe, Farisori, McMalamute, Estira- bot, Eduardosalg, Veon, Leonpolanco, Pan con queso, Mar del Sur, Alejandrocaro35, Botito777, Petruss, Alexbot, Darkicebot, Valentin estevanez navarro, RoyFokker, Raulshc, Açipni-Lovrij, SilvonenBot, Camilo, UA31, Ucevista, AVBOT, David0811, Flakinho, Nocturno- gatuno, MastiBot, Pedrito suarez, Angel GN, MarcoAurelio, Speedplus, Ezarate, Diegusjaimes, Jjflorescueto, Arjuno3, Andreasmperu, Luckas-bot, Virgi, Ptbotgourou, Jotterbot, Vic Fede, Dangelin5, Eduman~eswiki, Nixón, DSisyphBot, XZeroBot, ArthurBot, Ruy Pu- gliesi, Lcpousa, SuperBraulio13, M.heda, Xqbot, Jkbw, GhalyBot, Junior1209, Pedrovicenterosero, Calitb, Albertochoa, Igna, Torrente, Botarel, BenzolBot, Heynry1, Gusbelluwiki, Jhoelito14, TobeBot, Adrianantoniors, Imperioonepiece, Halfdrag, Aquiel, Mipataentutrasero, Wikielwikingo, Hantartico, KamikazeBot, , Abel406, TjBot, Alph Bot, Humbefa, Irvinopuma, Carlo el calvo, Shining.Star, Foundling, GrouchoBot, Xxxmagicmanxxx, Edslov, EmausBot, Savh, HRoestBot, Sergio Andres Segovia, Macrocoliset, Emiduronte, ChuispastonBot, MadriCR, Waka Waka, Xpress500, Mjbmrbot, Miguel hdez, Ksarasola, Metrónomo, Antonorsi, MerlIwBot, Papaplus, Renly, ClausxD, Arthur 'Two Sheds’ Jackson, Sebrev, Ginés90, Kotas, MetroBot, Henry bedon, Gusama Romero, Acratta, Metilisopropilisergamida, Vetra- nio, Elvisor, Sandovaltk10, Helmy oved, Syum90, Legobot, Eyetheunlord, Balles2601, ConnieGB, Angelrafa00, Jarould, Matiia, Egis57, Crystallizedcarbon, AlexGaitan, Deforetop6, Yholo, Andres477, Sapristi1000, CarlosAR2000, Benito Álvaro Cifuentes, Lalito312000, Benigno Jimenez Garay, Holaxddddd, Joltenick y Anónimos: 789 • Algoritmo determinista Fuente: http://es.wikipedia.org/wiki/Algoritmo%20determinista?oldid=71508940 Colaboradores: Riviera, Tano4595, Chobot, Yrbot, BOTijo, R0MAN0, CEM-bot, Nagul, Martínhache, Fsd141, Thijs!bot, Muro Bot, SieBot, DragonBot, DumZi- BoT, Luckas-bot, MystBot, SassoBot, JViejo, WikitanvirBot, KLBot2, Acratta, Elvisor, JacobRodrigues y Anónimos: 4 • Estructura de datos Fuente: http://es.wikipedia.org/wiki/Estructura%20de%20datos?oldid=81150159 Colaboradores: Edulix, Soniautn, Sabbut, Moriel, Sauron, Julie, Zwobot, Comae, Dodo, Triku, Fortran~eswiki, Sms, Rsg, Murphy era un optimista, Jsanchezes, LPR, Porao, Alexan, Emijrp, Rembiapo pohyiete (bot), RobotQuistnix, Platonides, Chobot, Yrbot, BOTijo, YurikBot, Icvav, KnightRider, Jesuja, Txo, Götz, Maldoror, Chlewbot, Tomatejc, Fercufer, Laura Fiorucci, Alexav8, Fsd141, Thijs!bot, Rasilga, Miguelo on the road, TXiKiBoT, Juan renombrado, Hidoy kukyo, Danthux, Humberto, Developer, Biasoli, AlnoktaBOT, VolkovBot, Matdrodes, YonaBot, BotMultichill, SieBot, Loveless, Furti, Alexbot, Açipni-Lovrij, SilvonenBot, Rrupo, AVBOT, David0811, MastiBot, MarcoAurelio, Diegusjaimes, DumZiBoT, Luckas-bot, Yonidebot, ArthurBot, Alexandravargas, SuperBraulio13, Ortisa, Xqbot, Jkbw, Asfarer, Ricardogpn, Botarel, Aquiel, Patru- BOT, Dinamik-bot, Crg 85, EmausBot, ZéroBot, WikitanvirBot, Manubot, Xerox 5B, Rezabot, MerlIwBot, Jetjanoli, V.aguado, Seasz, Addbot, DarkBlueZV y Anónimos: 79 • Cola (informática) Fuente: http://es.wikipedia.org/wiki/Cola%20(inform%C3%A1tica)?oldid=81430190 Colaboradores: Moriel, Jor- geGG, Robbot, Sms, Emijrp, BOTijo, The Photographer, Jesuja, Eduardo Lima, Jarke, CEM-bot, Thijs!bot, Diosa, Isha, JAnDbot, Pólux, AlnoktaBOT, Technopat, BotMultichill, SieBot, Ctrl Z, El3ctron, Loveless, BOTarate, Nubecosmica, Ken123BOT, WikiBotas, Tirithel, Kikobot, Farisori, Eduardosalg, Qwertymith, Jduarte, Poco a poco, Mithy, Alexbot, SilvonenBot, MastiBot, Diegusjaimes, Arjuno3, Jot- terbot, DSisyphBot, Amadeupons, Alvaromedina, Xqbot, Jkbw, PabloRCR, Josemgm89, Igna, Panderine!, Hprmedina, KamikazeBot, EmausBot, Africanus, Waka Waka, DOOM17, Syum90, Ocaroline, Addbot, Miguel940829, DarkBlueZV, Moispi y Anónimos: 72 • Tipo de dato abstracto Fuente: http://es.wikipedia.org/wiki/Tipo%20de%20dato%20abstracto?oldid=80031514 Colaboradores: Angus, Zwobot, Comae, RolanRBD, Ascánder, Sms, Avm, Elwikipedista, Beagle~eswiki, WhisKiTo, Rembiapo pohyiete (bot), RobotQuistnix, Platonides, Jcgarcianaranjo, YurikBot, Mortadelo2005, GermanX, Equi, KnightRider, Eskimbot, Maldoror, Leonardocaballero, CEM- bot, RaulFraileBeneyto, Anicholo~eswiki, Karshan, Thijs!bot, Alvaro qc, Javierrami, Bot que revierte, JAnDbot, TXiKiBoT, Netito777, Rei-bot, Idioma-bot, Fremen, Gomesbascoy, Technopat, Fernando Estel, Mjollnir1984, BOTarate, Tesi1700, Ken123BOT, Tirithel, Mi- guel, Eduardosalg, Juan Mayordomo, UA31, AVBOT, Santiagobas, DumZiBoT, Diádoco, ArthurBot, RedBot, Dinamik-bot, Ebrambot, ChuispastonBot, MadriCR, Pablombg, KLBot2, Robotsfuture, Bambadee, Fenixchava, JYBot, Addbot y Anónimos: 45 • Vector (informática) Fuente: http://es.wikipedia.org/wiki/Vector%20(inform%C3%A1tica)?oldid=81151693 Colaboradores: Juancri, Pino, Moriel, Sauron, Robbot, Dodo, Crescent Moon, Tano4595, Toad32767, Boticario, Taichi, LeCire, RobotQuistnix, Caiserbot, Dro- mero, Yrbot, BOTijo, YurikBot, GermanX, KnightRider, Jesuja, Götz, Maldoror, Chlewbot, Tomatejc, CEM-bot, Jorgelrm, JMCC1, Especiales, Baiji, Rosarinagazo, Clokr, IrwinSantos, JAnDbot, Spa karmona, LeinaD natipaC, TXiKiBoT, Kandorf, Netito777, Biasoli, Cinevoro, VolkovBot, Matdrodes, BlackBeast, Gmarinp, Muro Bot, BotMultichill, SieBot, Cholga~eswiki, Veon, Alejandrocaro35, Poco a poco, Juan Mayordomo, Darkicebot, SilvonenBot, Rrupo, Albambot, AVBOT, MastiBot, Diegusjaimes, DumZiBoT, CarsracBot, Ja- vu61, Luckas-bot, XZeroBot, SuperBraulio13, Xqbot, Jkbw, A. Guizar, Hprmedina, CVBOT, Yago AB, Dinamik-bot, Fran89, Pke93,
  • 51.
    11.8. TEXT ANDIMAGE SOURCES, CONTRIBUTORS, AND LICENSES 45 EmausBot, Savh, HRoestBot, Sergio Andres Segovia, Grillitus, MerlIwBot, Helmy oved, Makecat-bot, 2rombos, Miguel2706, Addbot, DonRulasRules, Jarould, Benigno Jimenez Garay y Anónimos: 116 • Pila (informática) Fuente: http://es.wikipedia.org/wiki/Pila%20(inform%C3%A1tica)?oldid=81315564 Colaboradores: Robbot, Vivero, Fortran~eswiki, Sms, Richy, Boticario, Emijrp, RobotQuistnix, FlaBot, BOTijo, YurikBot, GermanX, The Photographer, Jesuja, Banfi- eld, Fernd, Chlewbot, Rbonvall, Kn, BOTpolicia, CEM-bot, Laura Fiorucci, Rjelves, Thijs!bot, JoaquinFerrero, Isha, TXiKiBoT, Sirpup- pet, Pólux, Sebado, Biasoli, AchedDamiman, AlnoktaBOT, Cinevoro, Technopat, Matdrodes, Shooke, BotMultichill, SieBot, Loveless, Greek, Farisori, Botito777, Martaka, Sire, Poco a poco, Juan Mayordomo, BotSottile, Shalbat, AVBOT, Ezarate, Diegusjaimes, DumZi- BoT, MelancholieBot, Andreasmperu, Luckas-bot, MystBot, Nallimbot, Ptbotgourou, LyingB, GCaracuel, Xqbot, Jkbw, Ealmagro, Botarel, D'ohBot, Gbduende, KamikazeBot, Angelito7, Foundling, EmausBot, Savh, ZéroBot, HRoestBot, David f.1993, ChuispastonBot, Phaetton, WikitanvirBot, MerlIwBot, Harpagornis, Creosota, Helmy oved, Makecat-bot, Vengadora, Legobot, Ocaroline, Addbot, JacobRodrigues, DarkBlueZV, Moispi, David Condrey y Anónimos: 98 • Programa informático Fuente: http://es.wikipedia.org/wiki/Programa%20inform%C3%A1tico?oldid=82060404 Colaboradores: Ejme- za, Taichi, Magister Mathematicae, Chobot, Vitamine, GermanX, Gaijin, The Photographer, Banfield, CEM-bot, Jorgelrm, Nagul, Baiji, Jgomo3, Dorieo, Escarbot, RoyFocker, Cratón, Isha, JAnDbot, Jugones55, Gsrdzl, CommonsDelinker, VityUvieu, Gacq, Humberto, Ama- nuense, Idioma-bot, Pólux, Biasoli, Cinevoro, VolkovBot, Technopat, Queninosta, Matdrodes, Elabra sanchez, Shooke, Lucien leGrey, Gerakibot, SieBot, PaintBot, Rigenea, Bigsus-bot, BOTarate, Mel 23, Tirithel, Javierito92, HUB, Estirabot, Eduardosalg, Botellín, Leonpo- lanco, Alejandrocaro35, Botito777, Petruss, Açipni-Lovrij, UA31, SergioN, MARC912374, AVBOT, David0811, Angel GN, SubSeven- MoRpHeEuS, MarcoAurelio, NjardarBot, Diegusjaimes, Mikiguti, CarsracBot, Arjuno3, Saloca, Luckas-bot, Spirit-Black-Wikipedista, Roinpa, Dangelin5, Axel.axel, Nixón, ArthurBot, SuperBraulio13, Xqbot, Jkbw, Igna, Botarel, D'ohBot, BOTirithel, AnselmiJuan, Pa- truBOT, KamikazeBot, Rudol0075, Foundling, EmausBot, Bachi 2805, Savh, ZéroBot, HRoestBot, Grillitus, Rubpe19, Jcaraballo, Ma- driCR, AStarBot, MerlIwBot, Vagobot, MetroBot, BiTAlejandro, Elvisor, Helmy oved, Makecat-bot, Addbot, Balles2601, Amautita12, AVIADOR-bot, Jarould, Kevin15jdr, Beromawiki y Anónimos: 169 11.8.2 Images • Archivo:ALU_symbol.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/8/82/ALU_symbol.svg Licencia: CC-BY-SA-3.0 Colaboradores: Este gráfico vectorial fue creado con Inkscape. Artista original: en:User:Cburnett • Archivo:AlgoritmoRaiz.png Fuente: http://upload.wikimedia.org/wikipedia/commons/2/26/AlgoritmoRaiz.png Licencia: CC-BY-SA- 3.0 Colaboradores: Trabajo propio, hecho con OpenOffice.org Draw Artista original: Kn • Archivo:Arquitectura_von_Neumann.png Fuente: http://upload.wikimedia.org/wikipedia/commons/b/bd/Arquitectura_von_ Neumann.png Licencia: CC-BY-SA-3.0 Colaboradores: ? Artista original: ? • Archivo:Array1.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/3/3f/Array1.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Check_mark.png Fuente: http://upload.wikimedia.org/wikipedia/commons/f/f0/Check_mark.png Licencia: ? Colaboradores: Wikipedia Artista original: Wikipedia • Archivo:Classes_and_Methods.png Fuente: http://upload.wikimedia.org/wikipedia/commons/d/d0/Classes_and_Methods.png Licen- cia: CC BY-SA 3.0 Colaboradores: Using SublimeText Artista original: Bobbygammill • Archivo:CodeCmmt002.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/7/75/CodeCmmt002.svg Licencia: CC BY 2.5 Co- laboradores: Transferido desde en.wikipedia a Commons.28041964 Artista original: The original uploader was Dreftymac de Wikipedia en inglés • Archivo:Cola.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/b/bb/Cola.svg Licencia: CC BY-SA 3.0 Colaboradores: Image:Data_Queue.svg by User:Vegpuff Artista original: User:Vegpuff,User:Ocaroline User:Boivie • Archivo:ColaProg.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/5/5c/ColaProg.JPG Licencia: CC-BY-SA-3.0 Colabo- radores: Trabajo propio Artista original: Jduarte • Archivo:Commons-emblem-copyedit.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/e/e8/Commons-emblem-copyedit. svg Licencia: CC BY-SA 3.0 Colaboradores: • File:Gnome-emblem-important.svg Artista original: GNOME icon artists, Fitoschido • Archivo:Commons-emblem-question_book_orange.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/1/1f/ Commons-emblem-question_book_orange.svg Licencia: CC BY-SA 3.0 Colaboradores: <a href='//commons.wikimedia.org/ wiki/File:Commons-emblem-issue.svg' class='image'><img alt='Commons-emblem-issue.svg' src='//upload.wikimedia.org/ wikipedia/commons/thumb/b/bc/Commons-emblem-issue.svg/25px-Commons-emblem-issue.svg.png' width='25' height='25' srcset='//upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Commons-emblem-issue.svg/38px-Commons-emblem-issue.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Commons-emblem-issue.svg/50px-Commons-emblem-issue.svg.png 2x' data-file-width='48' data-file-height='48' /></a> + <a href='//commons.wikimedia.org/wiki/File:Question_book.svg' class='image'><img alt='Question book.svg' src='//upload.wikimedia.org/wikipedia/commons/thumb/9/97/Question_book.svg/25px-Question_book.svg.png' width='25' height='20' srcset='//upload.wikimedia.org/wikipedia/commons/thumb/9/97/Question_book.svg/38px-Question_book.svg. png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/9/97/Question_book.svg/50px-Question_book.svg.png 2x' data-file- width='252' data-file-height='199' /></a> Artista original: GNOME icon artists, Jorge 2701 • Archivo:Commons-logo.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/4a/Commons-logo.svg Licencia: Public domain Colaboradores: This version created by Pumbaa, using a proper partial circle and SVG geometry features. (Former versions used to be slightly warped.) Artista original: SVG version was created by User:Grunt and cleaned up by 3247, based on the earlier PNG version, created by Reidab. • Archivo:Computer-aj_aj_ashton_01.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/c/c1/Computer-aj_aj_ashton_01. svg Licencia: CC0 Colaboradores: ? Artista original: ? • Archivo:Dg-nova3.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/9/99/Dg-nova3.jpg Licencia: Copyrighted free use Co- laboradores: Photograph taken by Qu1j0t3. Artista original: User Qu1j0t3 on en.wikipedia
  • 52.
    46 CAPÍTULO 11.PROGRAMA INFORMÁTICO • Archivo:EsquemáticaAlgoritmo1.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/a/a3/Esquem%C3% A1ticaAlgoritmo1.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Kn • Archivo:FortranCardPROJ039.agr.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/5/58/FortranCardPROJ039.agr.jpg Licencia: CC BY-SA 2.5 Colaboradores: I took this picture of an artifact in my possession. The card was created in the late 1960s or early 1970s and has no copyright notice. Artista original: Arnold Reinhold • Archivo:Fuente_de_computadora.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/b/be/Fuente_de_computadora.JPG Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Cesar Eduardo Ballesteros Aguirre • Archivo:HP_Touchsmart_PC.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/40/HP_Touchsmart_PC.jpg Licencia: CC BY 2.0 Colaboradores: http://www.flickr.com/photos/36627423@N04/3377516586/ Artista original: Jannet • Archivo:LampFlowchart-es.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/b/bd/LampFlowchart-es.svg Licencia: CC BY-SA 3.0 Colaboradores: • LampFlowchart.svg Artista original: LampFlowchart.svg: svg by Booyabazooka • Archivo:Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png Fuente: http://upload.wikimedia.org/ wikipedia/commons/3/37/Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png Licencia: CC BY-SA 3.0 Colaboradores: Taking a screenshot, then editing using Paint.NET Artista original: Carrot Lord • Archivo:PCDESK.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/0/06/PCDESK.JPG Licencia: GFDL Colaboradores: Trabajo propio Artista original: Almiux2009 • Archivo:PET-basic.png Fuente: http://upload.wikimedia.org/wikipedia/commons/0/0b/PET-basic.png Licencia: Public domain Colabo- radores: Trabajo propio Artista original: Rafax • Archivo:Pauscal_lenguaje_de_programación.png Fuente: http://upload.wikimedia.org/wikipedia/commons/3/32/Pauscal_lenguaje_ de_programaci%C3%B3n.png Licencia: CC BY-SA 4.0 Colaboradores: Trabajo propio Artista original: DarkBlueZV • Archivo:Personal_computer,_exploded_4.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/1/13/Personal_computer% 2C_exploded_4.svg Licencia: CC BY 2.5 Colaboradores: ? Artista original: ? • Archivo:Pila.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/d/d1/Pila.svg Licencia: CC0 Colaboradores: Image:Data_ stack.svg by User:Boivie. Artista original: User:Boivie, User:Ocaroline • Archivo:Pilas.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/6/62/Pilas.jpg Licencia: CC BY-SA 4.0 Colaboradores: Tra- bajo propio Artista original: DarkBlueZV • Archivo:Programming_language_textbooks.jpg Fuente: http://upload.wikimedia.org/wikipedia/commons/a/a0/Programming_ language_textbooks.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: User:K.lee • Archivo:Python_add5_syntax.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/e/e1/Python_add5_syntax.svg Licencia: Copyrighted free use Colaboradores: http://en.wikipedia.org/wiki/Image:Python_add5_syntax.png Artista original: Xander89 • Archivo:Rename_icon.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/7/79/Rename_icon.svg Licencia: CC-BY-SA-3.0 Colaboradores: Image:Translation arrow.svg + Image:B with line below.svg, own work Artista original: Angr, Down10, Korrigan, User: Clarus The Dogcow • Archivo:Spanish_Wikiquote.SVG Fuente: http://upload.wikimedia.org/wikipedia/commons/1/13/Spanish_Wikiquote.SVG Licencia: CC BY-SA 3.0 Colaboradores: derived from Wikiquote-logo.svg Artista original: James.mcd.nz • Archivo:Translation_arrow.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/2/2a/Translation_arrow.svg Licencia: CC- BY-SA-3.0 Colaboradores: Este gráfico vectorial fue creado con Inkscape. Artista original: Jesse Burgheimer • Archivo:USB_flash_drive.JPG Fuente: http://upload.wikimedia.org/wikipedia/commons/2/2c/USB_flash_drive.JPG Licencia: CC-BY- SA-3.0 Colaboradores: ? Artista original: ? • Archivo:Wikibooks-logo-es.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/4/42/Wikibooks-logo-es.svg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: User:Bastique, User:Ramac et al. • Archivo:Wikibooks-logo.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/f/fa/Wikibooks-logo.svg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: User:Bastique, User:Ramac et al. • Archivo:Wikiversity-logo-Snorky.svg Fuente: http://upload.wikimedia.org/wikipedia/commons/1/1b/Wikiversity-logo-en.svg Licen- cia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Snorky • Archivo:Wiktionary-logo-es.png Fuente: http://upload.wikimedia.org/wikipedia/commons/0/06/Wiktionary-logo-es.png Licencia: CC BY-SA 3.0 Colaboradores: originally uploaded there by author, self-made by author Artista original: es:Usuario:Pybalo 11.8.3 Content license • Creative Commons Attribution-Share Alike 3.0 View publication statsView publication stats