Está en la página 1de 31

A lo largo de la historia, el término «paradigma» fue objeto de muchas

interpretaciones. En su origen griego, significaba «modelo», «ejemplo» o «patrón».


Sobre este punto de partida, podemos hablar de un paradigma como un conjunto
de creencias, prácticas y conocimientos que guían el desarrollo de una
disciplina durante un período de tiempo. En diversas ramas de la ciencia, un
conjunto de ideas en vigencia puede ser reemplazado drásticamente por otro que
entre en conflicto con él y se demuestre más acertado. La programación tiene sus
propios paradigmas, pero  el término «paradigma de programación» no
necesariamente representa un modelo único que deba ser respetado hasta que
aparezca otro mejor. De hecho, actualmente muchos paradigmas coexisten en
armonía.
Un paradigma de programación es un estilo de desarrollo de programas. Es
decir, un modelo para resolver problemas computacionales. Los lenguajes de
programación, necesariamente, se encuadran en uno o varios paradigmas a la vez
a partir del tipo de órdenes que permiten implementar, algo que tiene una relación
directa con su sintaxis.
¿Cuáles son los principales paradigmas de programación?

 Imperativo. Los programas se componen de un conjunto de sentencias que


cambian su estado. Son secuencias de comandos que ordenan acciones a
la computadora.
 Declarativo. Opuesto al imperativo. Los programas describen los resultados
esperados sin listar explícitamente los pasos a llevar a cabo para
alcanzarlos.
 Lógico. El problema se modela con enunciados de lógica de primer orden.
 Funcional. Los programas se componen de funciones, es decir,
implementaciones de comportamiento que reciben un conjunto de datos de
entrada y devuelven un valor de salida.
 Orientado a objetos. El comportamiento del programa es llevado a cabo
por objetos, entidades que representan elementos del problema a resolver y
tienen atributos y comportamiento.
Otros son de aparición relativamente reciente y no forman parte del grupo principal:

 Dirigido por eventos. El flujo del programa está determinado por sucesos
externos (por ejemplo, una acción del usuario).
 Orientado a aspectos. Apunta a dividir el programa en módulos
independientes, cada uno con un comportamiento bien definido.
Cada paradigma es ideal para la resolución de un conjunto de problemas particular,
por lo que no puede decirse que uno sea necesariamente mejor que otro.

https://www.4rsoluciones.com/blog/que-son-los-paradigmas-de-programacion-2/
Metodología para la solución de pasos por
computadora
La solución de un problema por computadora, requiere de siete pasos, dispuestos de tal forma
que cada uno es dependiente de los anteriores, lo cual indica que se trata de un proceso
complementario y por lo tanto cada paso exige el mismo cuidado en su elaboración. Los siete
pasos de la metodología son los siguientes:
    
1. Definición del problema.
2. Análisis de la solución.
3. Diseño de la solución.
4. Codificación.
5. Prueba y depuración.
6. Documentación.
7. Mantenimiento.

1.Definición de problema: Es el enunciado del problema, el cual debe ser claro y completo.
Es fundamental conocer y delimitar por completo el problema, saber que es lo que se desea
que realice la computadora, mientras esto no se conozca del todo, no tiene caso continuar con
el siguiente paso.

2. Análisis de la solución: Consiste en establecer una serie de preguntas acerca de lo que


establece el problema, para poder determinar si se cuenta con los elementos suficientes para
llevar a cabo la solución del mismo.

3. Diseño de la solución: Una vez definido y analizado el problema, se produce a la creación


del algoritmo (Diagrama de flujo o pseudocodigo) en el cual se da la serie de pasos ordenados
que nos proporcione un método explicito para la solución del problema.

4.Codificación: Consiste en escribir la solución del problema (de acuerdo al pseudocodigo); en


una serie de instrucciones detalladas en un código reconocible por la computadora; es decir un
lenguaje de programación (ya sea de bajo o alto nivel), a esta serie de instrucciones se le
conoce como PROGRAMA.

5.Prueba y depuración: Prueba es el proceso de identificar los errores que se presenten


durante la ejecución de programa, es conveniente que cuando se pruebe un programa se
tomen en cuenta los siguientes puntos:

- Trata de iniciar la prueba con una mentalidad saboteadora, casi disfrutando la tarea
de encontrar un error.
- Sospechar de todos los resultados que arroje la solución, con lo cual se deberán verificar
todos.
- Considerar todas las situaciones posibles, normales y aun las anormales.

La depuración consiste en eliminar los errores que se hayan detectado durante la prueba, para
dar paso a una situación adecuada y sin errores.

6. Documentación: Es la guía o comunicación escrita que sirve como ayuda para usar el
programa, o facilitar futuras modificaciones. A menudo, un programa escrito por una persona es
usado por muchas otras, por ello la documentación es muy importante; esta debe presentarse
en tres formas: EXTERNA, INTERNA y al USUARIO FINAL.

-Interna: Consiste en los comentarios o mensajes que se agregan al código de programa, que
aplican las funciones que realizan ciertos procesos, cálculos o formulas, para el entendimiento
del mismo.
-Externa: Está integrada por los siguientes elementos: Descripción del problema, nombre del
autor, diagrama de flujo y/o pseudocodigo, listas de variables y constantes, y codificación del
programa, esto con la finalidad de permitir su posterior adecuación a los cambios.

- Usuario Final: es la documentación que se le proporciona al usuario final, es una guía que
indica al usuario como navegar en el programa, presentando todas las pantallas y menús que
se va a encontrar y una explicación de los mismos, no contiene información de tipo técnico. 

7. Mantenimiento: Se lleva a cabo después de  terminado el programa, cuando se ha estado


trabajando un tiempo, y se detecta que es necesario hacer un cambio, ajuste
y/o complementación al programa para que siga trabajando de manera correcta. Para realizar
esta función el programa debe estar debidamente documentado, lo cual facilitará la tarea. 

http://pasossoluciondeproblemas.blogspot.com/2012/01/metodologia-para-la-solucion-de-
pasos.html

Introducción
La computadora y sus tecnologías colaterales, en el poco tiempo de existencia que tienen en
la práctica (unos cincuenta años), han sido uno de los factores de cambio más importantes
de nuestra sociedad. Nuestra sociedad admira la facilidad que tienen estas máquinas para
facilitar los procesos que realiza el hombre en su vida diaria.
Sin embargo, es notorio el desconocimiento generalizado acerca de lo que se debe hacer
para que la computadora pueda facilitarnos las cosas. Poca gente sabe que una
computadora debe "PROGRAMARSE ADECUADAMENTE" para que realice las cosas que
tanto nos maravillan. Además, de los que conocen esta verdad, solo una fracción sabe con
alguna certeza los pasos que se deben seguir para programar adecuadamente a la máquina.
Esta monografía pretende precisamente ilustrar, en términos generales, el proceso que se
debe seguir para lograr que un problema se resuelva, dentro de lo posible, haciendo uso de
la computadora.

Observaciones Preliminares
Cuando programamos una computadora, no hacemos más que señalar, a la máquina, una
serie de órdenes o instrucciones, que ella realizará exactamente, para procesar
la información que les suministramos.
El diseño de un programa de computadora (también llamado sistema computacional,
aplicación, o simplemente, sistema), es un proceso delicado. En él, en principio, le
señalamos a la máquina, exactamente, cuáles son los procesos que debe seguir para el
procesamiento de la información.
Es decir, "NOSOTROS" le señalamos a "LA COMPUTADORA" lo que debe hacer. Quién usa
la computadora, tiene la responsabilidad de señalarle "EXACTAMENTE", lo que debe
hacer. La máquina siempre realizará lo que programemos, y solamente eso. Todo lo que
hagamos usando computadorasdebe enmarcarse, necesariamente, dentro de este
lineamiento fundamental.
La programación de computadoras es, para la mayoría de las personas, un tema misterioso.
No se atreven a incursionar en él, tal vez porque temen a lo desconocido.
Esta monografía pretende, precisamente, darnos algunas luces acerca de esta materia.
La Creación De Programas Para Computadoras: Un Proceso Con Siete Pasos.
La creación de un programa de computadora significa más que el simple trabajo mecánico
del hombre y la máquina. Constituye la culminación de todo un proceso complejo, que
involucra a los dos entes, aportando cada uno su respectiva parte en la realización de la
tarea.
Esta tarea ha sido sistematizada por los especialistas del área, buscando optimizar
la eficiencia de los programas producidos. La sistematización comprende un proceso que
consta de siete pasos. Estos son:
 Definición del problema.
 Selección del método de solución.
 Creación del algoritmo.
 Programación del algoritmo.
 Depuración y documentación del programa.
 Validación de la solución.
 Instalación, producción y mantenimiento del programa.
La denominación exacta de cada uno de ellos, así como el número de pasos involucrados,
generalmente varía de un autor a otro. Sin embargo, en esencia, son la "APLICACIÓN
DEL MÉTODO CIENTÍFICO" a la solución de un problema práctico.
A continuación, nos referiremos a cada uno de estos pasos con más detenimiento.
Definición Del Problema.
La definición o enfoque del problema es el primer paso en el diseño de un programa de
computadora. Consiste, fundamentalmente, en definir cual es la "SITUACIÓN QUE
INTENTAMOS RESOLVER".
La definición del problema debe ser tan clara y precisa como sea posible, de modo que no
pueda ser malinterpretada por otras personas. Dicho requisito es muy difícil de lograr. Sin
embargo, este paso fundamenta todo lo que se hará en los otros pasos. Luego, no se puede
avanzar en el proceso sin contar con esa definición.
La importancia que reviste a esta etapa es enorme. Si el programador no entiende bien el
problema que enfrenta, es prácticamente imposible que la computadora lo comprenda
mejor. Ella no es capaz de señalar la solución que buscamos, sin embargo, está diseñada
para facilitar el estudio de los casos que analizamos, al procesar la información
suministrada con gran rapidez y exactitud.
Generalmente, no obtendremos la comprensión absoluta del problema en estudio, con el
primer intento. Es necesario realizar un proceso de tanteos y aproximaciones paulatinas
al dominio de la situación que analizamos. Es más, generalmente, debemos retroceder a las
etapas iniciales del proceso, debido a un detalle que se planteó ambiguamente al definir el
problema. El retroceso, al inicio del diseño, es obligatorio, aunque nos encontremos en sus
etapas finales.
Debemos enfocar la definición del problema, a través de las siguientes caracterizaciones:
 El modelo de situación típica que se estudiará.
 Las limitaciones impuestas.
 Los datos con que se cuenta.
 La información que se espera obtener.
 Las metas u objetivos a lograr al resolver el problema (este aspecto es sumamente
importante).
 Las alternativas disponibles para lograrlas.
 El balance de los criterios involucrados en el problema (velocidad, precisión,
confiabilidad de las respuestas, facilidad de uso, ..., entre otros).
Simultáneamente se establece el problema a resolver, deben diseñarse los objetivos
específicos que se espera lograr al resolverlo, así como el alcance que ellos tendrán. Estos
aspectos de la definición del problema se relacionan, íntimamente, entre sí.
El costo de ignorar dicha relación, generalmente, se refleja en los pasos siguientes. Ellos
resultarán más difíciles de alcanzar. Fácilmente tendremos que volver a replantear todo el
problema, debido a cualquier condición importante que pasaba inadvertida.
Esta situación es una molestia en cuanto al tiempo, dinero y esfuerzo humano que se
pierde, al retroceder en el diseño del programa. Sin embargo, es evidente que el precio de
este descuido supera, enormemente, el costo de hacer un estudio más detenido y minucioso
del problema.
Selección Del Método De Solución.
Cuando el problema está bien enfocado, se le tiene que encontrar una solución. El método
empleado para obtenerla puede ser planteado de distintas maneras. Pero, casi todos,
podemos agruparlos dentro de tres categorías básicas. Ellas son, en orden creciente de
importancia:
 Métodos geométricos.
 Métodos analíticos.
 Métodos iterativos.
A continuación, explicaremos con más detalle esta clasificación.
Métodos Geométricos.
Los métodos geométricos, generalmente, emplean gráficas para resolver los problemas.
Ellas pueden ser de tipo sintético o analítico.
Las construcciones de tipo sintético se realizan, comúnmente, dentro del marco de
la geometría euclidiana clásica. Es decir, se toman como base: los axiomas fundamentales
de la teoría, la observación directa de la figura, y las proposiciones previamente
demostradas. Con base a estas premisas, se derivan nuevas propiedades de las figuras. Este
enfoque geométrico es el más primitivo de los dos y para efectos de programación de
computadoras, no es funcional, en la actualidad.
Por otro lado, las construcciones de tipo analítico se realizan estableciendo un sistema de
ejes coordenados en la figura en estudio. A cada punto importante se le asocia un par
ordenado de números reales (que puede ser constante o variable). El par ordenado en
mención, esta dado en función a las coordenadas del punto con base al sistema referencial.
Las figuras, en tanto, serán representadas como ecuaciones; obtenidas a través de métodos
de sección y proyección de segmentos. Esta representación define una biyección entre
puntos geométricos y coordenadas algebraicas. En consecuencia, se transforma
el análisis geométrico en algebraico, empleando las reglas, herramientas y ecuaciones
típicas del álgebra.
De los dos enfoques, geométricos éste tiene más vigencia en la programación de
computadoras.
Un ejemplo del último enfoque, lo vemos en la solución de sistemas de ecuaciones
simultáneas por el método gráfico.
Métodos Analíticos.
Los métodos analíticos se basan en planteamientos derivados de las ramas clásicas de
las matemáticas abstractas (álgebra, geometría analítica y análisis matemático, entre otras).
Generalmente, consisten en la aplicación de una fórmula o método preestablecido, con base
a los supuestos con que fue construido. Ellos originan, el último enfoque para la solución de
problemas (los planteamientos iterativos).
La programación de estos métodos puede presentar grados muy diversos de dificultad
(dependiendo de cada fórmula particular).
Como ejemplo de ellos, tenemos la fórmula para la solución de una ecuación cuadrática, en
el caso general.
Métodos Iterativos.
Los métodos iterativos son el enfoque más importante para resolver problemas, usando
computadoras. También se fundamentan en las ramas clásicas de la matemática abstracta.
Se caracterizan porque emplean procesos iterativos y recurrentes en la solución de los
problemas (fundamentados en la teoría de sucesiones y series del análisis matemático).
Los métodos basados en técnicas iterativas y analíticas, forman la esencia de
la disciplina matemática conocida como "ANÁLISIS NUMÉRICO".
El análisis numérico trata de expresar y calcular, en forma tan exacta como sea posible,
algunos de los conceptos, métodos y expresiones matemáticas que son estudiadas dentro
del "ANÁLISIS MATEMÁTICO", tales como:
 Integrales definidas.
 Derivadas evaluadas en un punto.
 Funciones trigonométricas de un ángulo dado.
 Solución de ecuaciones diferenciales con valores a la frontera, entre otros tópicos.
El planteamiento de estas expresiones se realiza en función a métodos "CONSTRUCTIVOS"
que involucran un número finito de operacionesmatemáticas. En el análisis numérico, el
auxilio de los programas de computadora, generalmente, es imprescindible; por
el volumen de operaciones aritméticas y lógicas a realizar.
Independientemente de los tipos de métodos establecidos, en la práctica, la solución de un
problema puede involucrar la combinación de uno o más métodos conocidos, y hasta el
diseño de uno completamente nuevo.
Cuando no es posible encontrar una vía para resolver al problema, se hace necesario su
replanteamiento, para simplificarlo. En consecuencia, se facilita su solución. Por otro lado,
se ven casos en los que hay un procedimiento de solución que resulta obvio.
Su programación también puede presentar grados muy diversos de dificultad.
Como ejemplo de estos métodos, tenemos el cálculo de raíces de una función, empleando el
procedimiento de bisección de Bolzano.
Creación Del Algoritmo.
Cuando se ha escogido un método de solución, debemos establecerlo, por escrito, con tanto
detalle como sea posible. Se debe establecer como una secuencia de pasos "BIEN
DEFINIDA" y tan "COMPLETA" como sea posible, para conservar la claridad de la
definición del problema y del método que se aplicará en su solución.
No debe dejarse nada al azar. En ese sentido, si se presenta un problema particular, que el
método no puede resolver, él debe ser capaz, al menos, de informar al usuario que no puede
obtener una respuesta satisfactoria con ese enfoque.
Estas necesidades particulares se satisfacen a través del empleo de un algoritmo, que define
"INEQUÍVOCAMENTE" la lógica usada en la solución del problema. En esencia, ellos no
difieren significativamente de los usados dentro del álgebra cotidiana. En consecuencia,
debemos construirlos, hasta donde sea posible, empleando el lenguaje natural.
Sin embargo, a nivel de la programación de computadoras, debemos ajustar
el lenguaje natural a las tres clases fundamentales de órdenes estructuradas descendentes
(la asignación, la decisión y la repetición). Adicionalmente, se deben implementar, en el
algoritmo, estructuras adicionales de:
 Entrada y salida de la información.
 Cálculo numérico y manipulación de datos.
 Comparación lógica y relacional.
 Almacenamiento y recuperación de información.
Es importante resaltar en este punto, que cada algoritmo diseñado para resolver un
problema, está asociado a una estructura o tipo de datos que le permite administrar la
información del problema de manera más o menos eficiente. Dependiendo de esto, un
mismo problema se puede resolver de varias maneras, cada una de ellas con cierto grado de
eficiencia frente a las demás. Esto nos lleva a que en un momento dado podemos tener un
algoritmo eficiente, con una estructura de datos deficiente, o viceversa. Queda entonces al
buen juicio del analista, el decidir si es más importante tener un algoritmo o una estructura
de datos eficiente, para lograr la solución al problema originalmente planeado.
En todo caso, la creación de un algoritmo es un proceso repetitivo, que se refina
paulatinamente. Se parte de un esquema burdo de la lógica que soluciona el problema, y se
llega (luego de mucho esfuerzo), al grado de detalle que caracteriza a los programas de
computadora. Cuando logramos ese nivel en el planteamiento del algoritmo, su
programación se realiza prácticamente sin esfuerzo (se reduce a la "TRADUCCIÓN" de las
órdenes al formato que comprende la máquina).
Características Que Debe Reunir Todo Algoritmo.
Cuando creamos un algoritmo, debemos tratar de reunir, en él, una serie de características
importantes. Ellas nos garantizan que el algoritmo producido tiene un alto grado
de calidad. Estas son:
 Integridad.
 Claridad.
 Simplicidad.
 Eficacia.
 Modularidad.
 Generalidad.
A continuación, explicaremos con más detalle estas características.
 Integridad.

Esta característica se refiere a la exactitud y precisión de los cálculos involucrados. No tiene


sentido crear un algoritmo que tendrá un comportamientoimpredecible, y en consecuencia,
que manipule nuestra información de manera aleatoria.
 Claridad.

Es un aspecto más sutil. Se refiere a la legibilidad de la lógica involucrada. Si un algoritmo


es claro, es posible entregarlo a otra persona para que lo modifique, sin grandes
dificultades. Adicionalmente, el programador original podrá comprender y modificar su
lógica, aunque tenga mucho tiempo de haberla elaborado.
 Simplicidad.

Esta característica suele recoger a las dos anteriores. Si un algoritmo es fácil de


comprender, desde el punto de vista lógico, y manipula correctamente la información, su
simplicidad se establece como una consecuencia inmediata.
Santiago, 27 de diciembre de 1995.
SEÑORES REYES MAGOS:
Les extrañará mucho que les escriba hoy 27 de diciembre, pero es que quiero aclarar ciertas
cosas que han ocurrido desde el día primero de ese mismo mes, en que lleno de ilusión, les
envié mi cartita.
En la misma les pedía lo siguiente: una bicicleta, un trencito eléctrico, un par de patines,
dos revólveres con cartuchera, un traje de pelotero con su manilla de primera y el juego del
hombre nuclear con todos sus accesorios.
Me destrocé el cerebro estudiando todo el año, tanto que fui no sólo el primero de la clase,
sino que obtuve la mejor nota de todo el colegio o mejor dicho de la escuela pública en que
estoy. No les volví a mentir no hubo en todo el barrio quien se portara mejor que yo, con
mis padres, con mis amiguitos, con los vecinos, con todo el que necesitare de mi ayuda.
Pero que huevos más grandes los de ustedes, creen que es poca vaina lo que me han hecho,
dejando debajo de mi cama solamente un trompo y un par de medias y para acabar de
joder, el hijo de puta trompo no tiene hilo y las medias están rotas.
Que mierda es lo que se han creído, so pedazos de mierda, tríos de chuchas de su madre
sifilíticas, me han cogido de pendejo durante el año para salirme con ésta mariconada, y no
conforme con esto, el cuequito de mierda ese, hijo de la vieja culona a la que mi papá le
maneja el carro, el fulito ese culicagao, sin educación, mal parío, y desobediente, le han
llenado la casa de juguetes, de tal forma que están regados por la sala, el patio y hasta en el
excusado, y el muy hijo de puta, se puso a llorar porque quería mi trompo y el cabrón de mi
Papá se lo dio.
COÑO.... por eso es que aquí tiene que venir algo grande, porque con Reyes Magos tan
cabrones como ustedes, La Verga nadie se salva en este hijo de puta país. El que nace para
pingón que le crezcan las pelotas.
Chacarones de mierda, se van pa' la verga los tres, pajisos del carajo, no se dejen ver de mí
el año que viene, porque me voy a robar los pantys de mi hermana y con los elásticos voy a
hacerme unos biombos para entrarle a pedradas a esos camellos de mierda en los huevos
para que se espanten y tengan ustedes que joderse a pie, como estoy yo, ya que la bicicleta
que les pedí, era para ir a la escuela que queda más lejos que la chucha.
No quiero despedirme sin antes desearles que ojalá den el culo y les guste, partida de
maricones y que les acusen de comunistas, les corten los cojones y se los den de comer
antes de fusilarlos, sobre todo el negro de mierda de BALTAZAR a quien le dirigí la carta,
bien me decía mi papá... "no te fihes de los negros, que no son puercos que den manteca".
Y quiero que le digan a ese viejo maricón de Santa Claus, que no se preocupe, viejo
gonorriento, que ojalá le caigan ladillas en la barba, a él, que le pedí ayuda y ni mierda de
caso que me hizo. A todos ustedes les deseo un barranco de mierda para este año nuevo y el
año que viene ya sabrán de un muchachito cabrón e hijo de puta.
Muy Atentamente, Pepito...
 Eficacia.

La eficacia del algoritmo se refiere a su velocidad de ejecución y la administración eficiente


de los recursos de la máquina. Cuando nos enfrentamos a problemas complejos, que exigen
llevar los recursos disponibles al límite de su agotamiento, se hace imperativo que
los algoritmos sean eficaces, aun a expensas de su claridad. En estas situaciones, el sentido
común del programador juega un papel muy importante, pues debe decidir cuanto se
sacrificará una característica frente a la otra.
 Modularidad.

"DIVIDE Y VENCERÁS" dice un viejo adagio popular. Él, tiene vigencia en la creación de
algoritmos. Cuando nos enfrentamos a un problema complejo, es importante subdividirlo
en tareas más sencillas. En la mayoría de los casos, la modularidad de un algoritmo
incrementa su claridad, y eficiencia, simultáneamente. Sin embargo, el sentido común del
programador es el mejor catalizador de esta característica.
 Generalidad.

El esfuerzo de programar se hace inútil si no damos generalidad a los algoritmos, ya que se


tendrá que repetir todo el análisis del problema, cada vez que se plantea una situación no
contemplada en el estudio. Sin embargo, la generalidad de un algoritmo debe ser limitada,
generalmente a las tareas que se pueden prever de manera razonable. En ese sentido,
nuevamente, el sentido común juega un papel muy importante en el diseño de algoritmos.
Como ejemplo de un algoritmo representativo (bastante simple), podemos mencionar el
aplicado en el caso de las raíces de la ecuación cuadrática de coeficientes y raíces reales.
Programación Del Algoritmo.
Dependiendo del grado de precisión logrado en la etapa anterior, el paso que
mencionaremos en este apartado será, directamente, más sencillo de lograr.
En esencia, cada una de las pautas lógicas establecidas dentro del algoritmo, se debe
traducir a una instrucción equivalente en el lenguaje de programación. Así, las
características del algoritmo definen, directamente, las características de su programación.
Técnicamente, hablamos de "CODIFICAR EL ALGORITMO".
Posteriormente, el listado del programa es grabado en un medio de almacenamiento de la
computadora. Luego, es traducido al lenguaje de la máquina empleando un conjunto de
programas, denominados compiladores-enlazadores o intérpretes. Ellos,
siguen procedimientos específicos de empleo, dependiendo de cada sistema particular que
se use.
Muchos programadores novatos sienten la "TENTACIÓN" de escribir la solución del
problema directamente en el lenguaje de programación, sin completar las etapas previas a
este paso. Esta acción es una pérdida de tiempo, ya que generalmente, estos intentos no
abarcan la totalidad del problema, o dejan algunos detalles al azar. Estas fallas, en su
momento, se harán evidentes y habrá que retroceder a esta etapa.
La referencia a lenguajes de programación, compiladores-enlazadores, e intérpretes
amerita algunas aclaraciones adicionales.
Como mencionamos anteriormente, la programación del algoritmo consiste,
fundamentalmente, en su traducción a un formato equivalente, que comprende la
computadora (llamado lenguaje de máquina). Este proceso se logra a través del empleo de
una representación intermedia, denominada lenguaje de programación. Un lenguaje de
programación se puede definir, en consecuencia, como un sistema completo de
simbolismos, caracteres y reglas, que nos permiten comunicarnos con la computadora.
En teoría, todos los lenguajes de programación deben brindar la facilidad de implementar
las estructuras de datos y de control definidas dentro de los algoritmos. Pero, en realidad,
existe una marcada diferenciación en la implementación de cada uno de ellos. Estas
diferencias los ubican, individualmente, con debilidades, libertades y potencialidades
específicas, frente a un problema dado. Generalmente, aquellos que son más fáciles de usar
e implementan mayores posibilidades de programación, se denominan "LENGUAJES DE
ALTO NIVEL".
Los lenguajes de programación se implementan a través de los intérpretes y compiladores-
enlazadores. Ambos son programas, generalmente diseñados en lenguaje de máquina. Se
encargan de "TRADUCIR" las secuencias de órdenes de los programas escritos en un
lenguaje de programación de alto nivel, al lenguaje de máquina.
Los compiladores-enlazadores realizan la traducción de todas las órdenes a la vez; como un
todo, creando en el proceso un programa que puede ser ejecutado directamente en la
máquina sin depender del compilador-enlazador.
Los intérpretes, en cambio, realizan la traducción de las órdenes al lenguaje de máquina,
procesándolas y ejecutándolas una a una, dinámicamente. Los intérpretes no crean
programas ejecutables (como los creados por los compiladores-enlazadores).
Depuración Y Documentación Del Programa.
Es de humanos cometer errores, pero la verdad de esta afirmación es más evidente para
quienes han tenido experiencias en la programación de computadoras. Prácticamente
ningún analista logra que sus programas funcionen correctamente en el primer intento.
Debe someterlos a un proceso de corrección y depuración de errores de todo tipo.
Así, los compiladores-enlazadores e intérpretes requieren que el programa cumpla con toda
una serie de reglas semánticas y sintácticas preestablecidas dentro del lenguaje, para
realizar la traducción al lenguaje de máquina. Una coma mal ubicada, un paréntesis que
falte o sobre, una orden mal escrita; todas son situaciones que provocan que un programa
no se pueda compilar, o funcione incorrectamente.
Adicionalmente, en esta etapa podemos enfrentarnos a una serie de situaciones no previstas
dentro del proceso. El caso más importante lo vemos cuando surgen resultados incorrectos;
debido a que los algoritmos, que son exactos en teoría, sufren los problemas conocidos
como error por redondeo y error por truncamiento, de las cifras involucradas en los
cálculos. Sus efectos pueden ser tan catastróficos al aparecer, que llegan a invalidar
completamente la efectividad del algoritmo (es decir, harán que no resuelva el problema
originalmente planteado).
Estos errores deben ser eliminados del programa a través de un cuidadoso y exhaustivo
análisis de los procesos previos a este paso. Es decir, revisando el método de solución de
una manera más detenida y considerando los detalles de implementación en la
computadora.
Por otro lado, se deben crear documentos escritos, complementarios al programa diseñado.
Esta, información debe reunirse de manera histórica y sistemática, paralelamente a los
cambios que sufra el programa en su vida útil. Estos escritos se conocen como
"DOCUMENTACIÓN DEL SISTEMA" y deben reflejar, en lo posible, lo que pensaba el
programador al diseñar la aplicación. Debe reunir, entre otras cosas, detalles acerca de:
 La definición del problema que se intenta resolver.
 La descripción del método de solución empleado.
 "TODOS" los algoritmos y listados de los módulos que integran al programa principal y
sus partes.
 La enumeración detallada de "TODAS" las instrucciones que pueden realizar los
operadores del programa, así como "TODOS" los pasos para realizarlas correctamente
(manual del usuario).
 La administración del teclado, por parte del programa.
 Las convenciones que deben asumirse en el manejo de la información.
 Los controles para verificar la integridad de la información.
 Las limitaciones, libertades y potencialidades que tiene el programa.
Estos documentos deben reposar en el código fuente y en copias impresas separadas. Dicha
información se orienta a los posibles usuarios del programa y a los programadores que, en
el futuro, modifiquen su contenido.
La importancia de estos escritos se debe a que, el programador "GUARDA" la lógica del
sistema, en su mente, cuando está recién confeccionado. Sin embargo, con el transcurrir del
tiempo, esa información se olvida y, consecuentemente, el código fuente que una vez fue
claro, lógico y sencillo; nos parecerá incomprensible, e imposible de modificar.
La documentación que reposa en el código del programa se debe crear tan pronto se
completa cada parte del sistema, para lograr que los conceptos originalmente planteados se
coloquen íntegramente allí. Está orientada fundamentalmente hacia los programadores.
En tanto, la documentación escrita es de tipo más general y se orienta a los usuarios del
programa. Fundamentalmente, trata de auxiliar al usuario en la implementación del
sistema, explicando la naturaleza de la información que se suministra al programa, las
salidas que produce, y los procedimientos empleados para realizar éstas y otras
operaciones.
Resumiendo, esta información es importante para facilitar la depuración, mantenimiento y
posterior uso del sistema, por quienes no lo programaron.
Validación De La Solución.
Si nuestro algoritmo no a sido objeto de un estudio cuidadoso y profundo en las etapas
iniciales, al llegar a este punto, nos enfrentaremos a preguntas tales como:
 ¿Las soluciones obtenidas tienen sentido al enfrentarlas a la teoría del problema
planteado?
 ¿Los casos triviales son contemplados adecuadamente dentro del enfoque de la solución
planteada?
 ¿Se obtienen las soluciones correctas al aplicar el algoritmo a una amplia gama de
problemas específicos, con respuesta conocida?
 ¿Las simplificaciones realizadas inicialmente (al definir el problema) afectan al
algoritmo, al punto que sus resultados no tienen ninguna utilidadpráctica?
Las preguntas planteadas, evidentemente, no las puede responder la computadora. Es la
persona que realizó el análisis del problema quien debe enfrentarlas. Dependiendo del
grado de eficiencia que se logró en las etapas iniciales del análisis del problema, la
respuesta a estas preguntas será una trivialidad, o nos obligará a replantear todo
el proyecto desde la definición del problema. Esta etapa se cumple, a veces,
simultáneamente a la depuración del código fuente.
Instalación, Producción Y Mantenimiento Del Programa.
Finalmente, y luego de muchos esfuerzos, el programador logra que su diseño funcione
correctamente. Nuestro programa es instalado permanentemente como sistema y entra a la
fase de producción. En ella obtenemos los beneficios de la rapidez en los cálculos, al
resolver los problemas planteados, con gran velocidad y confiabilidad. En este momento,
podemos pensar que la faena del programador ha concluido. Desgraciadamente, eso es
falso.
La implantación del programa no se puede realizar a la ligera. Es necesario que se
establezca un período de "PRUEBA" para el sistema. En ese tiempo, se verificará que, en
realidad, el programa ejecuta todos los procesos originalmente contemplados en el diseño.
Esto se logra a través de la comparación de resultados logrados con la máquina, frente a los
obtenidos por métodos manuales. Si es necesario, el programa es nuevamente revisado y
corregido. Dichas correcciones deben ser reflejadas, lógicamente, en la documentación
escrita que lo acompaña.
Por otro lado, al igual que cualquier creación del hombre, los programas de computadora
no son eternos. Deben recibir un mantenimiento adecuado, con el objeto de que se
mantengan a tono con las necesidades que van surgiendo, dinámicamente, con el
transcurrir del tiempo.
Por ejemplo, pueden surgir nuevas situaciones que originalmente no fueron previstas, y
requieren la atención de quienes emplean el programa. En tal caso, el programa debe ser
modificado para adaptarlo a esas circunstancias imprevistas inicialmente.
Usualmente, el proceso de mantenimiento se lleva a cabo en tanto el programa sea
provechoso. Una vez deja de ser útil, sencillamente se abandona y la información que
manejaba (si es necesario) es transferida a otros sistemas para que la aprovechen.
Comentarios Finales.
El proceso al que nos hemos referido, se ve como algo bastante difícil y tedioso. Sin
embargo, la práctica de la programación de computadoras siguiendo este procedimiento,
acarrea grandes beneficios, a largo plazo. Entre ellos, tenemos la creación de programas
altamente confiables y eficientes. Para facilitar la comprensión de este proceso, hemos
confeccionado la figura que, a continuación, mostramos:

Figura 1: Los siete pasos necesarios para producir programas de calidad. Las flechas
con trazo continuo indican la secuencia a seguir, obligatoriamente. Las fechas punteadas
señalan que se puede retroceder en el proceso cuando sea necesario, para mejorar
el producto final.
Este proceso, permite desprender toda una serie de señalamientos bien claros, a manera de
conclusiones.
 La computadora no es capaz de resolver problemas por sí sola. Simplemente puede
realizar secuencias de pasos preestablecidas, a través de los programas que se le han
instalado.
 La computadora no releva al ser humano de la responsabilidad de estructurar su trabajo.
Al contrario, lo obliga a realizar una planificación más detallada y cuidadosa del mismo.
 La computadora no releva al hombre de interpretar los resultados obtenidos. Ella le
exige un conocimiento más amplio de los problemas que enfrenta, al tener que conjugar
una serie de situaciones no previstas cuando trabaja manualmente, y que pasan a formar
parte adicional del problema que enfrenta.
 La programación de computadoras puede resultar más simple para quienes tienen una
formación de índole matemática, que a los miembros de otras disciplinas (salvo,
lógicamente, los analistas y programadores de sistemas).
La última afirmación requiere algunas aclaraciones adicionales. Generalmente las personas
con formación matemática tienen la lógica altamente desarrollada y educada. Se les puede
facilitar, enormemente, la creación de métodos, algoritmos y programas, con respecto a los
integrantes de otras disciplinas del saber. Todo es cuestión de que, previamente, organicen
sus conocimientos lógicos, de modo que desarrollen las soluciones de los problemas en
función a las disposiciones de la programación estructurada descendente.
Sin embargo, esto no significa que alegremente podrán programar a las computadoras.
Ellos deben adquirir algunos conocimientos básicos de programación de computadoras y
análisis de sistemas de información.
Adicionalmente, esto no impide a las personas, que en general, son capaces de organizar
sus pensamientos de manera estructurada, que realicen la programación de computadoras
para resolver sus problemas personales. Todo depende del grado de organización de sus
ideas y planteamientos, además del dominio de algunos conceptos básicos de programación
de computadoras.

Bibliografía
 1. ALLEN SMITH, W. Análisis Numérico. Traducido por Francisco Javier Sánchez
Bernabe. Primera edición. México, D.F., México: Prentice-Hall, 1988. 608 páginas.
 2. CHAPRA, Steven, y CANALE, Raymond P. Métodos numéricos para ingenieros con
aplicaciones en computadoras personales. Traducido por Carlos Zapata S. Primera
edición. México D.F., México: McGraw-Hill, 1990. 641 páginas.
 3. GOTTFRIED, Byron S. Programación en Pascal. Traducido por Alfredo Bautista
Paloma. Primera edición. México D.F., México: McGraw-Hill, 1988. 398 páginas.
 4. JAMES, Merlin L, SMITH, Gerald M., y WOLFORD, James C. Métodos numéricos
aplicados a la computación digital con FORTRAN. Traducido por José A. Nieto Ramírez.
Primera edición. México, D.F., México: Representaciones y Servicios de Ingeniería,
1973. 575 páginas.
 5. JOYANES AGUILAR, Luis. Turbo Basic. Manual de Programación. Primera
edición. Madrid, España: McGraw-Hill, 1989. 525 páginas.
 6. HENRICE, Peter. Elementos de análisis numérico. Traducido por Federico Velasco
Coba. Primera edición. México, D.F., México: Trillas, 1972. 363 páginas.
 7. KORFHAGE, Robert R. Lógica y algoritmos: Con aplicaciones a las ciencias de la
computación e información. Traducido por Federico Velasco C. Primera edición. México,
D.F., México: Limusa, 1970. 222 páginas.
 8. LIPSCHUTZ, Seymour. Estructura de datos. Traducido por Manuel Ortega Ortíz de
Apodaca y Luis Hernández Yañez. Primera edición. México, D.F., México: McGraw-Hill,
1987. 390 páginas.
 9. LUTHE, Rodolfo, OLIVERA, Antonio, y SCHUTZ, Fernando. Métodos numéricos.
Primera edición. México, D.F., México: Limusa, 1986. 443 páginas.
 10. MCCRAKEN, Daniel D., y DORN, William S. Métodos numéricos y programación
FORTRAN. Traducido por José A. Nieto Ramírez. Primera edición. México, D.F.,
México: Limusa, 1986. 476 páginas.
 11. NELL, Dale, y LILLY, Susan C. Pascal y estructura de datos. Traducido por José
María Troya Linero. Primera edición. México, D.F., México: McGraw-Hill, 1988. 491
páginas.
 12. PALMER, Scott D. Domine Turbo Pascal 6. Traducido por Eduardo de la Calle
Suárez. Primera edición. México, D.F., México: Ventura, 1992. 597 páginas.
 13. PHILIPPAKIS, A. S. y KAZMIER, Leonard J. Diseño de programas con aplicaciones
en COBOL. Traducido por José María Troya Linero. Primera Edición. Madrid, España:
McGraw-Hill, 1984. 239 páginas.
 14. RALSTON, Anthony. Introducción al análisis numérico. Traducido por Carlos E.
Cervántes de Gortari. Primera edición. México, D.F., México: Limusa, 1970. 629
páginas.
 15. REINHARDT, Fritz y SOEDER, Heinrich. Atlas de matemáticas 1: Fundamentos,
álgebra y geometría. Traducido por Juan Luis Vázquez Suárez y Mario Rodríguez
Artalejo. Primera edición. Madrid, España: Alianza Editorial, 1984. 265 páginas.
 16. SANDERS, Donald H. Informática: Presente y futuro. Traducido por Roberto Luis
Escalona. Tercera Edición. México D.F., México: McGraw-Hill, 1991. 887 páginas.
 17. SANTALÓ SORS, Marcelo, y CARBONELL CHAURE, Vicente. Geometría Analítica.
Primera Edición. México D.F., México: Librería de Manuel Porrúa, 1959. 255 páginas.
 18. SCHEID, Francis. Análisis numérico. Traducido por Hernando Alonso Castillo.
Primera Edición. México D.F., México: McGraw-Hill, 1972. 422 páginas.
 19. SCHEID, Francis. Introducción a la ciencia de las computadoras. Traducido por
Alberto Jaime Sisa. Segunda Edición. México D.F., México: McGraw-Hill, 1985. 402
páginas.
 21. SCHEID, Francis, y Di Constanzo, Rosa Elena. Métodos numéricos. Traducido por
Gabriel Nagore Cázares. Segunda Edición. México D.F., México: McGraw-Hill, 1991. 709
páginas.
 22. SEEN, James A. Análisis y diseño de sistemas de información. Traducido por
Edmundo Gerardo Urbina Medal y Óscar Alfredo Palmas Velasco. Segunda Edición.
México D.F., México: McGraw-Hill, 1992. 942 páginas.
 23. SQUIRE, Enid. Introducción al diseño de sistemas. Traducido por Jaime Luis Valls
Cabrear. Primera Edición. México D.F., México: Fondo Educativo Interamericano, 1984.
345 páginas.

https://www.monografias.com/trabajos105/uso-computadoras-solucion-problemas/uso-
computadoras-solucion-problemas.shtml

La sintaxis de un lenguaje de programación se define como el conjunto de


reglas que deben seguirse al escribir el código fuente de los programas para
considerarse como correctos para ese lenguaje de programación.

La sintaxis de JavaScript es muy similar a la de otros lenguajes de programación


como Java y C. Las normas básicas que definen la sintaxis de JavaScript son las
siguientes:

 No se tienen en cuenta los espacios en blanco y las nuevas líneas:


como sucede con XHTML, el intérprete de JavaScript ignora cualquier
espacio en blanco sobrante, por lo que el código se puede ordenar de
forma adecuada para entenderlo mejor (tabulando las líneas, añadiendo
espacios, creando nuevas líneas, etc.)
 Se distinguen las mayúsculas y minúsculas: al igual que sucede con la
sintaxis de las etiquetas y elementos XHTML. Sin embargo, si en una
página XHTML se utilizan indistintamente mayúsculas y minúsculas, la
página se visualiza correctamente, siendo el único problema la no
validación de la página. En cambio, si en JavaScript se intercambian
mayúsculas y minúsculas el script no funciona.
 No se define el tipo de las variables: al crear una variable, no es
necesario indicar el tipo de dato que almacenará. De esta forma, una
misma variable puede almacenar diferentes tipos de datos durante la
ejecución del script.
 No es necesario terminar cada sentencia con el carácter de punto y
coma (;): en la mayoría de lenguajes de programación, es obligatorio
terminar cada sentencia con el carácter ;. Aunque JavaScript no obliga a
hacerlo, es conveniente seguir la tradición de terminar cada sentencia
con el carácter del punto y coma (;).
 Se pueden incluir comentarios: los comentarios se utilizan para añadir
información en el código fuente del programa. Aunque el contenido de
los comentarios no se visualiza por pantalla, si que se envía al navegador
del usuario junto con el resto del script, por lo que es necesario extremar
las precauciones sobre la información incluida en los comentarios.
JavaScript define dos tipos de comentarios: los de una sola línea y los que
ocupan varias líneas.

Ejemplo de comentario de una sola línea:

// a continuación se muestra un mensaje

alert("mensaje de prueba");

Los comentarios de una sola línea se definen añadiendo dos barras oblicuas ( //)
al principio de la línea.

Ejemplo de comentario de varias líneas:

/* Los comentarios de varias líneas son muy útiles

cuando se necesita incluir bastante información

en los comentarios */

alert("mensaje de prueba");

Los comentarios multilínea se definen encerrando el texto del comentario entre


los símbolos /* y */.

https://uniwebsidad.com/libros/javascript/capitulo-1/sintaxis
Creo que la mejor forma más práctica de entender la diferencia entre
la semántica y la sintaxis en un lenguaje de programación (en tu caso
quieres que sea el lenguaje C) es definiendo los errores semánticos y
los errores sintácticos.

- Errores sintácticos: cuando existe código inválido que el


compilador no entiende. Por ejemplo, intentas multiplicar una variable
string (cadena) con un integer (entero) en C. El compilador lo
detectará porque no puede compilarlo así. O cuando olvidas cerrar
algún paréntesis o algún corchete, es un error sintáctico.

- Errores semánticos: el código de programación es válido porque el


compilador lo entiende, pero el programa resultante no hace lo que el
programador quiere que haga. No hay forma de que el compilador
detecte estos errores.

Los errores semánticos son "errores lógicos", la lógica detrás del


código escrito no hace lo que el programador cree que hará.

Te daré varios errores semánticos en C:

// Sumar uno 1 a la variable X


x -= 1;

En este caso estamos restándole 1 a la variable X.

// Sumar 1 a la variable X
y += 1;

En este caso estamos sumándole 1 a la variable Y (no a X, que es la


que necesitamos).
// Actualizar todos los elementos de A

for (size_t i=1; i


 update(A[i]);

En este caso nos estamos olvidando de actualizar al arreglo A en su


posición 0, es decir A[0], por lo que se trata de un error semántico.

Veamos un último ejemplo:

int CalcularArea( int ancho, int largo )


{
return ancho + largo;
}

En la función anterior, la sintaxis en C es correcta, pero hay un error


semántico. En realidad para calcular el área del rectángulo se debería
multiplicar en lugar de sumar.

En la figura 1 mostramos el esquema básico del proceso de compilación de


programas, módulos y creación de bibliotecas en C. En este gráfico,
indicamos mediante un rectángulo con esquinas redondeadas los diferentes
programas involucrados en estas tareas, mientras que los cilindros indican los
tipos de ficheros (con su extensión habitual) que intervienen.

  

Figure 1: Esquema del proceso de compilación


(generación de programas ejecutables) en C
Este esquema puede servirnos para enumerar las tareas de programación
habituales. La tarea más común es la generación de un programa ejecutable.
Como su nombre indica, es un fichero que contiene código directamente
ejecutable por el procesador. Éste puede construirse de diversas formas:

1.

A partir de un fichero con código fuente.

2.

Enlazando ficheros con código objeto.

3.

Enlazando el fichero con código objeto con una biblioteca.

Las dos últimas requieren que previamente se hayan construido los ficheros
objeto (opción 2) y los ficheros de biblioteca (opción 3). Como se puede
comprobar en el esquema anterior, la creación de éstos tambien está
contemplada en el esquema. Así, es posible generar únicamente ficheros
objeto para:
1.

Enlazarlos con otros para generar un ejecutable. La primera alternativa


exige que uno de los módulos objeto que se van a enlazar contenga la
función main(). Esta forma de construir ejecutables es muy común y
usualmente los módulos objeto se borran, ya que no tiene interés su
permanencia. Si realmente es así, se opta por la otra alternativa.

2.

Incorporarlos a una biblioteca.

Una biblioteca, en la terminología de C, será una colección de módulos


objeto. Entre ellos existirá alguna relación, que debe entenderse en un
sentido amplio: si dos módulos objeto están en la misma biblioteca,
contendrán funciones que trabajen sobre un mismo tema (por ejemplo,
funciones de procesamiento de cadenas de caracteres).

Si el objetivo final es la creación de un ejecutable, en última instancia


uno o varios módulos objeto de una biblioteca se enlazarán con un
módulo objeto que contenga la función main().

Todos estos puntos se discutirán con mucho más detalle posteriormente.


Ahora, introducimos de forma muy general los conceptos y técnicas más
importantes del proceso de compilación en C.

2. El Preprocesador

El preprocesador acepta como entrada código fuente y se encarga de:

1.

Eliminar los comentarios.

2.

Interpretar y procesar las directivas de preprocesamiento,


precedidas siempre por el símbolo #.

Dos de las directivas más comúnmente empleadas en C


son #include y #define:

 #include: Sustituye la línea por el contenido del fichero especificado.


Por ejemplo, #include <stdio.h> incluye el fichero stdio.h, que
contiene declaraciones de tipos y funciones de entrada/salida de la
biblioteca estándar de C. La inclusión implica que todo el contenido del
fichero incluído sustituye a la línea #include.

 #define: Define una constante (identificador) simbólico.

Sustituye las apariciones del identificador por el valor especificado,


salvo si el identificador se encuentra dentro de una constante de cadena
de caracteres (entre comillas).

Por ejemplo, #define MAX_SIZE 100 establece el valor de la constante


simbólica MAX_SIZE a 100. En el programa se utilizará la constante
simbólica y el preprocesador sustituye cada aparación de MAX_SIZE por
el literal 100 (de tipo int).

En el capítulo 3 tratamos con más profundidad estas directivas y algunas otras


más complejas. En cualquier caso, retomando el esquema mostrado en la
figura 1 destacaremos que el preprocesador no genera un fichero de salida (en
el sentido de que no se guarda el código fuente preprocesado). El código
resultante se pasa directamente al compilador. Así, aunque formalmente
puden distinguirse las fases de preprocesado y compilación, en la práctica el
preprocesado se considera como la primera fase de la compilación.
Gráficamente, en la figura 2 mostramos el esquema de la fase de compilación.
Este tema lo desarrollamos en la sección 3 de este capítulo y en el capítulo 4,
donde describimos el funcionamiento del compilador de C implementado por
GNU (gcc).

  

Figure 2: Fase de compilación


   
3. El compilador

El compilador (del inglés, compiler) analiza la sintaxis y la semántica del


código fuente preprocesado y lo traduce, generando un fichero que contiene el
código objeto. La extensión por defecto de estos ficheros es .o (GNU)
ó .OBJ (Borland C). El programa proporcionado por GNU para realizar la
compilación es gcc (las siglas gcc son el acrónimo de GNU C Compiler). En el
capítulo 4 discutimos con detalle el funcionamiento y las opciones más
relevantes de gcc. Este programa puede usarse para realizar únicamente la
compilación (construcción de módulos objeto) si en su llamada se especifica
el parámetro -c. Por ejemplo, dado un módulo fuente llamado prueba.c, el
correspondiente módulo objeto se construye ejecutando:
gcc -c -o prueba.o prueba.c

Sin embargo, en la siguiente sección veremos que gcc puede utilizarse para


invocar de forma impícita al programa enlazador. Esto se consigue llamando
a gcc sin el agumento -c: el comportamiento por defecto de gcc es crear un
ejecutable, esto es, compilar y enlazar.

Antes de continuar, debemos hacer una importante observación. En el proceso


de compilación se interpreta el código fuente salvo las referencias a objetos
externos (funciones o variables) en el módulo de código que se está
compilando. Estos objetos externos, especialmente funciones, se declaran en
este módulo, pero se definen en otros. La declaración servirá al compilador
para comprobar que las referencias externas son sintácticamente correctas.

Veamos con un ejemplo muy simple e ilustrativo de que esto que hemos
comentado lo encontramos muy a menudo. Supongamos un fichero .c que
contiene la función main(). En ella se usa una instrucción printf(). Para
comprobar si la sintaxis es correcta, el compilador necesita conocer el
prototipo de esta función: de ahí que nuestro programa necesite incluir el
módulo de cabecera stdio.h. Sin embargo, el código ``ejecutable'' asociado a
esta función se encuentra en otro fichero (una biblioteca del sistema) por lo
que la traducción de nuestro programa se hará dejando el ``hueco''
correspondiente a la función printf(). Este hueco lo completará el enlazador
a partir de una biblioteca del sistema, generando definitivamente un código
ejecutable.
   
4. El enlazador

El enlazador (del inglés, linker) resuelve las referencias a objetos externos que


se encuentran en un fichero fuente. Estas referencias son a objetos que se
encuentran en otros módulos compilados, ya sea en forma de ficheros objeto o
incorporados en alguna biblioteca (del inglés, library).

El programa enlazador proporcionado por GNU es ld. Sin embargo, no es


usual llamar a este programa explícitamente sino que éste es invocado
convenientemente por el compilador gcc: cuando se llama a gcc y uno de los
ficheros involucrados es un módulo objeto o un fichero de biblioteca, el
último paso que realiza gcc es llamar al enlazador ld. Así, vemos que gcc es
más que un compilador (formalmente hablando) ya que al llamar a gcc se
proprocesa el código fuente, se compila, e incluso se enlaza.

Para generar un fichero ejecutable se requiere que uno de los módulos objeto
que se están enlazando contenga la función main(). A modo de ejemplo,
supongamos un fichero llamado principal.c que contiene la función main().
En este fichero se hace uso de la función que calcula el seno, cuyo prototipo
(declarado en math.h) es el siguiente: double sin(double x). Se quiere generar
un fichero ejecutable a partir de este módulo fuente.
#include <stdio.h>
#include <math.h>
...
int main (void)
{
...
double s, x;
...
scanf ("%f", &x);
...
s = sin (x);
printf ("El seno de %3.2f es %3.2f\n", x, s);
...
}

Cuando el compilador procesa este código no puede generar código ejecutable


ya que no puede completar la referencia a la función sin(): lo único que
encuentra en math.h es el prototipo o declaración de la función sin(). Así, el
código ejecutable asociado a este cálculo no puede completarse y queda
``pendiente''. Puede comprobarse empíricamente. La ejecución del comando
gcc -o principal principal.c
produce un error de enlace ya que el enlazador no encuentra el código
asociado a la función sin(). Para que se genere el código ejecutable habrá
que indicar explícitamente que se enlace con la biblioteca matemática:
gcc -o principal principal.c -lm

El lector más inquieto puede sorprenderse en este punto, ya que en este


programa, además de sin() se ha utilizado la función printf() y ésta no se ha
definido en el programa (sólo se ha introducido su declaración con la
directiva include <stdio.h>) ni se ha especificado, a la hora del enlace, en
qué biblioteca se encuentra. Afortunadamente, ciertas bibliotecas se enlazan
automáticamente a la hora de crear ejecutables, y la función printf() se
encuentra en una de ellas. Esta es la razón de que no se indique de forma
explícita en la llamada a gcc.

5. Uso de bibliotecas

C es un lenguaje muy reducido. Muchas de las posibilidades incorporadas en


forma de funciones en otros lenguajes, no se incluyen en el repertorio de
instrucciones de C. Por ejemplo, el lenguaje no incluye ninguna facilidad de
entrada/salida, manipulación de cadenas de caracteres, funciones matemáticas,
gestión dinámica de memoria, etc.

Esto no significa que C sea un lenguaje pobre. Todas estas funciones se


incorporan a través de un amplio conjunto de bibliotecas que no forman parte,
hablando propiamente, del lenguaje de programación. No obstante, como
indicamos anteriormente, algunas bibliotecas se enlazan automáticamente al
generar un programa ejecutable, lo que induce al error de pensar que, por
ejemplo, printf() es una función propia del lenguaje C. Otra cuestión es que
se ha definido y estandarizado la llamada biblioteca estándar de C (en
realidad, bibliotecas) de forma que cualquier compilador que quiera tener el
``marchamo'' de compatible con ANSI C debe asegurar que las funciones
proporcionadas en esas bibliotecas se comportan de forma similar a como
especifica el comité ANSI. A efectos prácticos, las funciones de la biblioteca
estándar pueden considerarse parte del lenguaje C.

Aún teniendo en cuenta estas consideraciones, el conjunto de bibliotecas


disponible y las funciones incluidas en ellas pueden variar de un compilador a
otro y el programador responsable deberá asegurarse que cuando usa una
función, ésta forma parte de la biblioteca estándar: este es el procedimiento
más seguro para construir programas transportables entre diferentes
plataformas y compiladores.

Cualquier programador puede desarrollar sus propias bibliotecas de funciones


y enriquecer de esta manera el lenguaje de una forma completamente
estandarizada. En la figura 1 se muestra el proceso de creación y uso de
bibliotecas propias. En esta figura se ilustra que una biblioteca es, en realidad,
una ``objetoteca'', si se nos permite el término. De esta forma nos referimos a
una biblioteca como a una colección de módulos objeto. Estos módulos objeto
contendrán el código objeto correspondiente a variables, constantes y
funciones que pueden usarse por otros módulos si se enlazan de forma
adecuada.

El programa de GNU que se encarga de incorporar, eliminar y sustituir


módulos objeto en una biblioteca es ar. En realidad, ar es un programa de
aplicación más general que la gestionar bibliotecas de módulos objeto pero no
entraremos en ello ya que no es de nuestro interés. En el
capítulo 6 explicamos con detalle la forma en que se gestionan y enlazan
bibliotecas, profundizando en el funcionamiento del programa ar.

http://www.it.uc3m.es/~pedmume/asignaturas/2005/LAO/Lab2/tutorial4/www-etsi2.ugr.es/
depar/ccia/mp2/old/apoyo/modelo/modelo.html

Programación modular. El método más conocidos para resolver un problema es


dividirlo en problemas más pequeños, llamados subproblemas. Esta técnica se usa
mucho en programación ya que programar no es más que resolver problemas, y se
le suele llamar diseño descendente, metodología del divide y vencerás o
programación top-down.

Concepto
La programación modular es un paradigma de programación que consiste en
dividir un programa en módulos o subprogramas con el fin de hacerlo más legible y
manejable.

Funció n
De los métodos más conocidos para resolver un problema, es dividirlo en
problemas más pequeños, llamados subproblemas. De esta manera, en lugar de
resolver una tarea compleja y tediosa, resolvemos otras más sencillas y a partir de
ellas llegamos a la solución. Esta técnica se usa mucho en programación ya que
programar no es más que resolver problemas, y se le suele llamar diseño
descendente, metodología del divide y vencerás o programación top-down.

Es evidente que si esta metodología nos lleva a tratar con subproblemas, entonces


también tengamos la necesidad de poder crear y trabajar con subprogramas para
resolverlos. A estos subprogramas se les suele llamar módulos, de ahí viene el
nombre de programación modular. En Pascal disponemos de dos tipos de
módulos: los procedimientos y las funciones.
Tipos
Los pará metros por valor
Los parámetros por valor tiene dicho nombre porque lo que recibe el subprograma
no son más que copias de los valores de los datos que el programa invocador le
pasa. Por tanto si en el procedimiento modificamos alguno de estos valores, los
datos originales permanecerán inalterados

Los pará metros por referencia


En cambio, en los parámetros por referencia lo que se pasa al procedimiento son
los datos en sí. Y si éste los modifica, los cambios permanecerán una vez que la
ejecución vuelva al módulo que invocó al procedimiento. Se utilizan para obtener
valores de los cálculos que haga un subprograma.

Ejemplos de la Programació n Modular


Un ejemplo de cómo emplear el diseño descendente para resolver un problema.
Supongamos que un profesor quiere crear un programa para gestionar las notas
de sus alumnos. Quiere que dicho programa le permita realizar tareas tales como
asignar notas, cambiar notas, ver las notas según distintas calificaciones, etc. A
continuación tienes un esquema que representa una de las posibles divisiones del
problema en módulos.

Historia
Se presenta históricamente como una evolución de la programación
estructurada para solucionar problemas de programación más grandes y
complejos de lo que esta puede resolver.

Objetivos de la Programació n Modular


Al aplicar la programación modular, un problema complejo debe ser dividido en
varios subproblemas más simples, y estos a su vez en otros subproblemas más
simples. Esto debe hacerse hasta obtener subproblemas lo suficientemente
simples como para poder ser resueltos fácilmente con algún lenguaje de
programación. Esta técnica se llama refinamiento sucesivo, divide y vencerás o
análisis descendente (Top-Down).

Un 'módulo' es cada una de las partes de un programa que resuelve uno de los
subproblemas en que se divide el problema complejo original. Cada uno de estos
módulos tiene una tarea bien definida y algunos necesitan de otros para poder
operar. En caso de que un módulo necesite de otro, puede comunicarse con éste
mediante una interfaz de comunicación que también debe estar bien definida.

Si bien un módulo puede entenderse como una parte de un programa en


cualquiera de sus formas y variados contextos, en la práctica se los suele tomar
como sinónimos de procedimientos y funciones. Pero no necesaria ni
estrictamente un módulo es una función o un procedimiento, ya que el mismo
puede contener muchos de ellos. No debe confundirse el término "módulo" (en el
sentido de programación modular) con términos como "función" o "procedimiento",
propios del lenguaje que lo soporte.

¿Qué es la recursividad?

Es una técnica utilizada en programación que nos permite que un


bloque de instrucciones se ejecute un cierto número de veces (el que
nosotros determinemos). A veces es algo complicado de entender,
pero no os preocupéis. Cuando veamos los ejemplos estará clarísimo.
En Java, como en otros muchos lenguajes, los métodos pueden
llamarse a sí mismos. Gracias a esto, podemos utilizar a nuestro favor
la recursividad en lugar de la iteración para resolver determinados
tipos de problemas.

Ejemplo sencillo
Vamos a ver un pequeño ejemplo que no hace absolutamente nada.
Es un método cuyo único objetivo es llamarse a sí mismo:

void cuentaRegresiva () {
cuentaRegresiva();

 Si ejecutáis esto, os va a dar un error en la pila (mítico StackOverflow


Error, Biblia de los programadores).

Como véis, he llamado al método cuentaRegresiva porque vamos a


mostrar por pantalla la cuenta atrás de un número que nosotros
pasemos como parámetro a la función. Por ejemplo, para hacer la
cuenta atrás de 10 sin recursividad, haríamos:

for( int i = 10; i >= 0; i--) {

System.out.println(i);

 Ahora, para hacerlo de manera recursiva, tendríamos que pasar como


parámetro un número. Además, tras imprimir ese número, llamaremos
a la misma función con el número actual restando uno:

void cuentaRegresiva(int numero) {

System.out.println(numero);

cuentaRegresiva(numero - 1);

Es lo que os he comentado arriba. Llamamos a la función con un 10.


Imprimimos el 10 y llamamos a la función con un 9. Imprimimos el 9 y
llamamos a la función con un 8. Así hasta el fin de los días. Digo hasta
el fin de los días porque os va a saltar error si ejecutáis esto así
directamente:

public class Recursividad {

static void cuentaRegresiva(int numero) {

System.out.println(numero);

cuentaRegresiva(numero - 1);

}
public static void main(String[] args) {

cuentaRegresiva(10);

 Problema: llamada infinita. Para ello, lo que tenemos que hacer es


que cuando el número sea 0, deje de llamar a la función. Para eso,
metemos una estructura condicional de toda la vida. Gracias al
condicional, dejará de ejecutarse a partir de 0:

void cuentaRegresiva(int numero) {

System.out.println(numero);

if(numero > 0) {

cuentaRegresiva(numero - 1);

Factorial
Calcular el factorial de un número con recursividad es el típico ejemplo
para explicar este método de programación. Recordad que el factorial
de un número es multiplicar dicho número por todos sus anteriores
hasta llegar a 1. Se representa con una exclamación. Por ejemplo:
5! = 54321 = 120 El recorrer los números hacia atrás ya lo tenemos
hecho. Ahora lo que queda es multiplicar ese número por su anterior, y
así sucesivamente:

int factorial(int n) {

if (n == 0) {

return 1;

} else {

return n * factorial(n - 1);

}
}

Si ya queréis simplificarlo al máximo y dejar a vuestros amigos con la


boca abierta, haced esto:

int factorial(int n) {

return (n == 0) ? 1 : n * factorial(n - 1);

Espero que os haya servido el tutorial para aprender algo más sobre
programación. Recordad que esto está hecho en Java, pero vale para
otros lenguajes.
¡Un saludo! Imagen: artdecomexico.com
Supongamos que en lugar de concatenar el resultado de la llamada recursiva
a aCadena con la cadena de cadenaConversion, modificamos nuestro algoritmo para incluir
las cadenas en una pila antes de hacer la llamada recursiva. El código de este algoritmo
modificado se muestra en el ActiveCode 1.
RunLoad History

1
from pythoned.basicas.pila import Pila
2

3
pilaResultados = Pila()
4

5
def aCadena(n,base):
6
cadenaConversion = "0123456789ABCDEF"
7
while n > 0:
8
if n < base:
9
pilaResultados.incluir(cadenaConversion[n])
10
else:
11
pilaResultados.incluir(cadenaConversion[n % base])
12
n = n // base
13
resultado = ""
14
while not pilaResultados.estaVacia():
15
resultado = resultado + str(pilaResultados.extraer())
16
return resultado
17

18
print(aCadena(1453,16))
19

Conversión de un entero a una cadena usando una pila (lst_recstack)

Cada vez que hacemos una llamada a aCadena, incluimos un carácter en la pila. Volviendo
al ejemplo anterior podemos ver que después de la cuarta llamada a aCadena la pila se
vería como muestra la Figura 5. Tenga en cuenta que ahora podemos simplemente extraer
los caracteres de la pila y concatenarlos en el resultado final, "1010".

Figura 5: Cadenas colocadas en la pila durante la conversión


Figura 5: Cadenas colocadas en la pila durante la conversión
El ejemplo anterior nos da una idea de cómo implementa Python una llamada a función
recursiva. Cuando se llama a una función en Python, se asigna un marco de pila para
manejar las variables locales de la función. Cuando la función realiza la devolución, el
valor devuelto se deja en el tope de la pila para que la función invocante tenga acceso a él.
La Figura 6 ilustra la pila de llamadas después de la instrucción return de la línea 4.
Figura 6: Pila de llamadas generada por aCadena(10,2)
Figura 6: Pila de llamadas generada por aCadena(10,2)
Note que la llamada a aCadena(2//2,2) deja como valor devuelto un "1" en la pila. Este
valor devuelto se utiliza entonces en lugar de la llamada de función ( aCadena(1,2)) en la
expresión "1" + cadenaConversión[2%2], que dejará la cadena "10" en el tope de la pila.
De esta manera, la pila de llamadas de Python reemplaza la pila que usamos
explícitamente en el Programa 4. En nuestro ejemplo de sumatoria de números en una
lista, usted puede pensar en el valor devuelto en la pila como una sustitución de una
variable de acumulación.
Los marcos de pila también proporcionan un entorno para las variables utilizadas por la
función. A pesar de que estamos llamando a la misma función una y otra vez, cada
llamada crea un nuevo entorno para las variables que son locales a la función.

 Next Section - 4.7. Visualización de la recursividad
user not logged in

También podría gustarte